Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR-303规范),配合BindingResult可以直接提供参数验证结果。
@Valid属于javax.validation包下,是jdk给提供的 是使用Hibernate validation的时候使用
@Validated是org.springframework.validation.annotation包下的,是spring提供的 是只用Spring Validator校验机制使用
说明:java的JSR303声明了@Valid这类接口,而Hibernate-validator对其进行了实现
@Validation对@Valid进行了二次封装,在使用上并没有区别,但在分组、注解位置、嵌套验证等功能上有所不同,这里主要就这几种情况进行说明。
在检验Controller的入参是否符合规范时,使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同:
- 分组
@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制,这个网上也有资料,不详述。@Valid:作为标准JSR-303规范,还没有吸收分组的功能。
- 注解地方
@Validated:用在类型、方法和方法参数上。但不能用于成员属性(field)
@Valid:可以用在方法、构造函数、方法参数和成员属性(field)上 所以可以用@Valid实现嵌套验证
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
public class Param {
@Min(20)
int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
@Valid验证情况1:
/**
* 有实现类hibernate-validator的情况生效,无实现类的情况下不生效(也不报错)
* @param param
* @return
*/
@PostMapping("/get")
public String get(@Valid @RequestBody Param param) {
System.out.println(param.getA());
return param.getA() + "ss";
}
@Valid验证情况2:
/**
* 有无实现类hibernate-validator的情况均不生效,因为只能对Object的属性进行校验,不能对单个的参数进行校验
* @param a
* @return
*/
@GetMapping("/test")
public String get(@Valid @Min(20) int a) {
System.out.println(a);
return a + "ss";
}
@Validated验证情况1:
/**
* 有实现类hibernate-validator的情况生效,无实现类的情况下不生效(也不报错)所以底层还是用的hibernate-validator实现
* @param param
* @return
*/
@PostMapping("/get")
public String get(@Validated @RequestBody Param param) {
System.out.println(param.getA());
return param.getA() + "ss";
}
Spring validator 方法级别的校验
JSR和Hibernate validator的校验只能对Object的属性进行校验,不能对单个的参数进行校验,spring 在此基础上进行了扩展,添加了MethodValidationPostProcessor拦截器,可以实现对方法参数的校验,实现如下:
https://www.cnblogs.com/softidea/p/12192444.html
1、实例化MethodValidationPostProcessor(springboot项目不用手动添加,框架自动装配bean)
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
returnnew MethodValidationPostProcessor();
}
2、在所要实现方法参数校验的类上面添加@Validated,如下
/**
* @Validated注解必须放在类上面,否则单方法参数校验不生效
* 官方说明:方法里写有JSR校验注解要想其生效的话,要求类型级别上必须使用@Validated标注(还能指定验证的Group)
* https://docs.spring.io/spring-framework/docs/5.3.8-SNAPSHOT/reference/html/core.html#validation-beanvalidation-spring-method
*/
@RestController
@RequestMapping("/t2")
@Validated
public class Test2Controller {
}
3、在方法上面添加校验规则:
@GetMapping("/test")
public String get(@Min(20) int a) {
System.out.println(a);
return a + "ss";
}
当方法上面的参数校验失败,spring 框架就回抛出异常
{
"timestamp": "2021-05-19T11:28:24.967+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/t2/test"
}