概述
很早的时候写过一篇文章Spring-BeanValidation校验@RequestParam参数, 只是简单记录了怎么使用BeanBalidation。这篇文章会介绍怎么使用JAVA BeanValidation,怎么自定义constraint注解,最后会介绍下Spring中怎么集成使用BeanValidation。
JSR303 java的数据验证的规范,为 JavaBean 验证定义了相应的元数据模型和 API。在应用程序中,通过使用 Bean Validation或是你自己定义的constraint,例如 @NotNull, @Max, @Min, 就可以确保数据模型的正确性。constraint注解可以加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发自定义constraint。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。
我们经常使用的Hibernate validator,就是在JSR303的基础上对校验注解进行了扩展。基本的constraint我这里就不说了,可以查看javax.validation.constraints包下的源码及说明。
自定义constraint
项目总经常用到单价,对于价格一般都需要判断大于0且不为空。我们以单价的约束为例,自定义对单价的约束枚举。
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Repeatable(UnitPrice.List.class)
@Documented
@Constraint(validatedBy = {PriceConstraintValidator.class})
public @interface UnitPrice {
String message() ;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* 最小单价
*/
int value();
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@interface List {
UnitPrice[] value();
}
}
以上定义可以参考NotNull的定义。核心的主要关注@Constraint(validatedBy={})这个元注解。这个即表明了此注解对应约束条件的实现,可以查看Constraint的源码,需要指定ConstraintValidator接口的实现类。那我们继续定义具体约束的实现类。
public class PriceConstraintValidator implements ConstraintValidator<UnitPrice, Double> {
private int price1;
@Override
public void initialize(UnitPrice unitPrice) {
price1 = unitPrice.value();
}
@Override
public boolean isValid(Double value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
return value >= price1;
}
}
当然我们的单价不一定只是Double类型,我们还可以定义Integer类型的约束判断,实现方式类似。
通过以上的定义,我们就可以使用@UnitPrice注解来对参数进行约束了,使用方法等同于@NotNull。
Spring validator集成
1.Spring容器注入MethodValidationPostProcessor对象
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
注意:如果Sping配置文件和SpringMVC配置文件分别独立,需要把这个配置加到SpringMVC配置中
2.使用@Validated注解
在对应的Controller或者Service中加上@Validated注解,当然也可以加到独立的请求方法中
3.使用校验注解
@RestController
@Validated
public class TestController {
@RequestMapping("/test")
public String test(@NotBlank(message = "姓名不能为空") @RequestParam("name") String name) {
// .....
return ResponseVO.successWithNoData("ok");
}
}
Service中使用
@Validated
public class ValidationService {
public int test(@Valid User user) {
System.out.println(user);
return 1;
}
public int test(@Min(3) int user) {
System.out.println(user);
return 1;
}
}
4.全局校验异常捕捉处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleValidationException(ConstraintViolationException e){
for(ConstraintViolation<?> s:e.getConstraintViolations()){
return s.getInvalidValue()+": "+s.getMessage();
}
return "请求参数不合法";
}
}
小结
以后再也不用对每个参数手写代码校验了,省下时间回家陪妹子。
https://www.cnblogs.com/beiyan/p/5946345.html
https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html
https://www.cnblogs.com/qq3111901846/p/6632289.html