JFinal JSR303 Valication 参数验证机制

今天受文章 http://www.jfinal.com/share/440  启发,尝试了一下,把经常用于spring项目的参数验证机制加入到jfinal项目中,运行正常。分享一下过程,直接上代码

public class ValidatorUtil {
  
   
   /**
    * 对象校验,默认group
    * @param t 待校验对象
    */
   public static <T> ValidateResult validatorObj(T t){
      return validatorObj(t, Default.class);
   }
   
   /**
    * 对象校验
    * @param t 待校验对象
    * @param groups 组
    * @return
    */
   public static <T> ValidateResult validatorObj(T t, Class<?>...groups){
      ValidateResult result = new ValidateResult();
      Set<ConstraintViolation<T>> constraintViolations = Validation.buildDefaultValidatorFactory().getValidator().validate(t, groups);
      Iterator<ConstraintViolation<T>> iter = constraintViolations.iterator();
      StringBuffer errorMsg = new StringBuffer();
      String op = "";
      while (iter.hasNext()) {
         result.setValid(false);
            String message = iter.next().getMessage();  
            errorMsg.append(op).append(message);
            op = ",";
        }
        result.setErrorInfo(errorMsg.toString());
      return result;
   }
}



public class BaseController extends Controller {

    /**
     * 获取参数生成bean,并校验
     * @param beanClass
     * @param <T>
     * @return
     * @throws
     */
    public <T> T getValidatedBean(Class<T> beanClass)  {
        T bean = super.getBean(beanClass,"");
        if(bean==null){
            renderJson(new BaseResult(ErrorType.PARAM_ERROR,"参数不允许为空"));
            return null;
        }
        ValidateResult validateResult = ValidatorUtil.validatorObj(bean);
        if(!validateResult.isValid()){
            renderJson(new BaseResult(ErrorType.PARAM_ERROR,validateResult.getErrorInfo()));
            return null;
        }
        return bean;
    }


}


public class UserRegisterParam {
    private String name;
    private  String email;

    @NotNull(message = "请提供姓名")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Email(message = "请提供正确邮箱")
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}


public class UserController extends BaseController {

    public void reg(){
        UserRegisterParam newUser = getValidatedBean(UserRegisterParam.class);
        if(newUser==null){ return;}
    }

}

jdk1.7环境下引入jar包

<dependency>
   <groupId>javax.validation</groupId>
   <artifactId>validation-api</artifactId>
   <version>1.1.0.Final</version>
</dependency>
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>5.1.1.Final</version>
</dependency>

针对restful api 测试结果

image.png

需要应用于render视图的可酌情修改

评论区

Dreamlu

2017-12-05 09:41

@a铖 海哥的jboot是用的jfinal-java8,jfinal-java8支持方法入参,跟使用spring校验使用上一致:https://my.oschina.net/qq596392912/blog/1580019 , 非java8版本,用起来没那么爽,有侵入,而且你这个UserController如果为null不能return呢?你怎么搞,哈哈哈,其实jfinal本身依赖了cglib,jfinal-java8基于cglib拿到方法参数名,不强制依赖java也是可以的。不过java10都出来了,何必再去兼容7、6,java8的stream,lambda爽得飞起~

Dreamlu

2017-12-05 09:42

不强制依赖java8也是可以的,掉了个8

Dreamlu

2017-12-05 09:48

我觉得实在是要兼容jfinal的话,使用拦截器去实现还是完美些,个人建议的话,可以自定义一个注解,@ValidBean({"xxx", "xx"}) 这种丢在方法上,xxx为getBean里面的名字。

a铖

2017-12-05 10:08

@Dreamlu 只是提供个类似思路,期望用最少的代码关联实现参数校验

JFinal

2017-12-05 11:33

先点赞、收藏,有时间的时候看一下是否可以改进这里,感谢你的分享

JFinal

2017-12-05 11:34

@Dreamlu jfinal-java8 这个 jfinal 版本的 action 参数注入并不依赖于 cglib,而是 java8 自带的 API

cglib 目前仅用于支持业务层 AOP,而且也只是个过渡,有时间会将 cglib 干掉,让 jfinal 重回“对第三方无依赖”

Dreamlu

2017-12-05 11:59

@JFinal 了解,我的意思是可以依赖cglib兼容jdk6、7,用cglib读取class字节码比较方便

JFinal

2017-12-05 12:27

@Dreamlu 后续会干掉 cglib 依赖,但可以考虑实现 cglib 中的核心功能,一是用来实现业务层 AOP、二是用来实现你建议的让 jdk6、7 都可以用上这个 aciton 参数注入的功能

lyh061619

2017-12-17 11:32

@JFinal 这个“一是用来实现业务层 AOP、二是用来实现你建议的让 jdk6、7 都可以用上这个 aciton 参数注入的功能”真是个爆表的功能啊顶顶个。^_^

热门分享

扫码入社