在程序中,参数校验是有个重复的工作,在不同的接口可能需要编写相同的校验逻辑,而 JSR 定义了 JavaBean 参数校验的元数据模型以及API。
JSR
JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
JSR-303
JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 ,Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。JSR 303 用于对 Java Bean 中的字段的值进行验证。Spring MVC 3.x 之中也大力支持 JSR-303,可以在控制器中对表单提交的数据方便地验证。
BeanValidation
在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情。应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成。很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等。为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定。
Bean Validation 为 JavaBean 验证定义了相应的元数据模型和 API。缺省的元数据是 Java Annotations,通过使用 XML 可以对原有的元数据信息进行覆盖和扩展。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint,例如 @NotNull, @Max, @ZipCode , 就可以确保数据模型(JavaBean)的正确性。constraint 可以附加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的 constraint。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。
JSR303 在项目中的实践
- 引入相关依赖
<!-- validation组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 传入参数前添加@Valid 注解,这样就可以对传入参数做相应的校验
public RespBean doLogin(@Valid LoginVo loginVo){
return userService.doLogin(loginVo);
}
- 在定义的参数类中,对其属性添加注解,进行校验
@NotNull
@Length(min = 32)
private String password;
注解的种类有很多,具体需要用到什么注解,可以进入javax.validation.constraints包内查看,如果没有合适的校验注解,可以自定义注解组件,进行校验。
JSR303进阶-创建自定义组件
//验证手机号
@Target( { METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {isMobileValidator.class})
public @interface IsMobile {
boolean required() default true;
String message() default "手机号码格式错误";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
项目要求对手机号码格式进行校验,仿照NotNull注解,构建IsMobile注解的框架,具体校验规则,在isMobileValidator.class校验类中实现。
public class isMobileValidator implements ConstraintValidator<IsMobile,String> {
private boolean required = false;
@Override
public void initialize(IsMobile constraintAnnotation) {
required = constraintAnnotation.required();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context){
if(required) {
return ValidatorUtil.isMobile(value);
}else {
if (StringUtils.isEmpty(value)) {
return true;
} else {
return ValidatorUtil.isMobile(value);
}
}
}
}
//手机号码校验
public class ValidatorUtil {
private static final Pattern mobile_pattern = Pattern.compile("[1](3-9)[0-9]{9}$");
public static boolean isMobile(String mobile){
if(mobile != null) {
return Pattern.matches("^1[3-9]\\d{9}$", mobile);
}
return false;
}
}
将自定义注解创建完成后,在定义的参数类中,添加相应注解。
@NotNull
@IsMobile
private String mobile;
完成!