jfinal整合Hibernate-validator校验框架

时间:2021-07-19 18:23:35

       做服务器开发时,我们接收到前端传来的参数都需要进行校验,判断参数是否合法,现在基本都是采用最傻逼且最苦逼的方法,就是在每个函数里都进行参数校验,但是有很多相同的参数都要在不同函数里重复出现校验的代码,比如用户注册时需要校验手机号码、密码、年龄和验证码;用户登录时需要校验手机号码和密码,用户修改信息时需要校验年龄,于是乎,每个请求方法里都相同的校验判断语句,如图:
jfinal整合Hibernate-validator校验框架
       反复复制粘贴相同的参数校验代码,导致代码臃肿且难维护,如此low的工作,作为程序肯定很鄙夷的。于是引出今天的主角Hibernate Validator!
       我们在项目中添加hibernate-validator-4.3.0.Final.jar、validation-api-1.0.0.GA.jar和jboss-logging-3.1.0.CR2.jar包,然后编写的参数校验拦截器ParamValidateInterceptor.java
详细代码:


import java.lang.reflect.Method;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.pstone.psccs.core.BaseAPIController;
import com.pstone.psccs.core.plugin.ioc.ValidParameter;
/**
*
* <p>Title:ParamValidateInterceptor </p>
* <p>Description: 参数校验拦截器</p>
*
* <p>Company:杭州权石科技有限公司 </p>
* @author: linzhuowei
*
* @date:2016年10月28日 上午10:12:05
*/

public class ParamValidateInterceptor implements Interceptor{
private static Validator validator = null;
public ParamValidateInterceptor(){
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}

@SuppressWarnings("unchecked")
@Override
public void intercept(Invocation inv) {
//获取controller类里所有声明的方法
Method[] methods = inv.getController().getClass().getDeclaredMethods();
BaseAPIController apiController = (BaseAPIController)inv.getController();
int errors = 0;
for(Method method : methods){

if(inv.getActionKey().endsWith("/"+method.getName()) ){//找到当前请求所调用的方法
ValidParameter valid = method.getAnnotation(ValidParameter.class);

if (valid != null) {
Class<?> validBean = valid.validBean();//获取需要校验的java bean
Class<?> []groups = valid.groups();
Set<?> constraintViolations = null;

if(groups!= null && groups.length > 0){
//支持分组校验
constraintViolations = validator.validate(apiController.getRequestObject(validBean),groups);
}else{
constraintViolations = validator.validate(apiController.getRequestObject(validBean));
}

if( constraintViolations != null){
errors = constraintViolations.size();
}

if ( errors > 0 ){

String msg = "";
for (Object constraintViolation : constraintViolations) {
msg += ((ConstraintViolation)constraintViolation).getMessage()+";";
}

apiController.renderFaile(10001, msg);
return;
}
}
break;
}
}

if( 0 == errors){//没有错误就放行
inv.invoke();
}
System.out.println("apiController="+apiController);
apiController.paramJson = null;//清空参数

}

}

然后把该拦截器注册为全局拦截器
jfinal整合Hibernate-validator校验框架
再编写标识为需要进行参数校验的注解ValidParameter

@Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运行时可通过反射获取 
@Target(ElementType.METHOD)//目标是方法
@Documented//文档生成时,该注解将被包含在javadoc中,可去掉
public @interface ValidParameter {
/**
* 校验的java bean类
* @return
*/

Class<?> validBean() default Void.class;
/**
* 注解分组
* @return
*/

Class<?>[] groups() default {};
}

接下来就是在需求参数校验的请求方法上添加注解@ValidParameter标识为需要校验的,(添加@ValidParameter就说明该请求方法需要进行参数),此时请求方法体顿时干净清爽了。
jfinal整合Hibernate-validator校验框架
然后在接收参数的java bean(UserInfo类)中进行编写各个参数校验的规则
jfinal整合Hibernate-validator校验框架

在页面上提交表单参数
jfinal整合Hibernate-validator校验框架
服务器处理请求返回结果为:
jfinal整合Hibernate-validator校验框架
       到此,你是不是拍案叫好了呢?但是还有问题存在,例如:用户登录和用户修改信息请求方法都是用UserInfo这个Java bean来接收参数,而用户登录时只需校验手机号码和密码而已,
用户修改信息时只需校验年龄而已,这时提交用户登录请求就会把其他多余的字段也进行校验了,这显然不符合业务需求。如下图:
jfinal整合Hibernate-validator校验框架

因此需要修改UserInfo类里每个字段的校验分组
jfinal整合Hibernate-validator校验框架
同时还要在每个请求方法函数的@ValidParameter注解上标明使用哪个分组进行校验
jfinal整合Hibernate-validator校验框架
修改完之后,再次在用户登录表单上提交错误数据,此时校验结果就正确了:
jfinal整合Hibernate-validator校验框架

其中RegisterGroup、UpdateGroup分组接口定义如下:
jfinal整合Hibernate-validator校验框架

  好了,jfinal整合hibernate validator框架到此就结束,更多、更高级的使用方法请上hibernate validator官网查看相应文档。