相关文章:
在处理前端页面传来的参数的时候,我们通常会对数据进行校验,从而保证程序的稳定性,这时候我们就会用到 @Valid 和 @Validated 这两个注解,而这两个注解又可以相互替代使用,那么它们之间究竟有什么区别呢,让我们一起来看看
一、区别
-
所属包不同
-
@Valid
- @Valid 位于 javax.validation 包,由 JDK 提供
-
@Validated
- @Validated 位于 org.springframework.validation.annotation 包,由 Spring 提供
-
-
是否提供分组功能
-
@Valid
- @Valid 不提供分组功能
-
@Validated
- @Validated 提供分组功能
-
-
是否提供验证排序功能
-
@Valid
- @Valid 不提供验证排序功能
-
@Validated
- @Validated 提供验证排序功能
-
二、校验相关类
-
分组接口类
public interface First { }
public interface Second { }
-
校验实体类
@Data public class Person { @NotEmpty(groups = First.class, message = "姓名不能为空") private String name; @Max(value = 18, groups = Second.class,message = "年龄不能超过18岁") private String age; @Max(value = 1, message = "性别只能为0和1: 0=女1=男") @Min(value = 0, message = "性别只能为0和1: 0=女1=男") private Short sex; }
-
json 请求参数
{ "name": "", "age": 19, "sex": 10 }
三、校验分组功能
-
@Validated 注解不加分组参数
-
控制层
@RestController @RequestMapping(value = "/verify") @Slf4j public class VerifyController { @PostMapping(value = "/valid") public void verifyValid(@Valid @RequestBody Person person, BindingResult result) { log.info("I am verifyValid() method, the request params is: 【{}】", person); if (result.hasErrors()) { FieldError fieldError = result.getFieldError(); if (fieldError != null) { log.error("error msg: 【{}】", fieldError.getDefaultMessage()); } } } @PostMapping(value = "/validated") public void verifyValidated(@Validated @RequestBody Person person, BindingResult result) { log.info("I am verifyValidated() method, the request params is: 【{}】", person); if (result.hasErrors()) { FieldError fieldError = result.getFieldError(); if (fieldError != null) { log.error("error msg: 【{}】", fieldError.getDefaultMessage()); } } } }
-
校验结果
-
@Valid
-
@Validated
-
由上可知,在 @Validated 注解不加分组参数的情况下 (@Valid 注解没有分组参数),多次校验下我们会发现不管是 @Valid 注解还是 @Validated 注解都只会校验没有添加 groups 属性的实体类字段 (此处只校验了 sex 字段)
-
-
-
@Validated 注解加分组参数
-
控制层
@RestController @RequestMapping(value = "/verify") @Slf4j public class VerifyController { @PostMapping(value = "/valid") public void verifyValid(@Valid @RequestBody Person person, BindingResult result) { log.info("I am verifyValid() method, the request params is: 【{}】", person); if (result.hasErrors()) { FieldError fieldError = result.getFieldError(); if (fieldError != null) { log.error("error msg: 【{}】", fieldError.getDefaultMessage()); } } } @PostMapping(value = "/validated") public void verifyValidated(@Validated(value = First.class) @RequestBody Person person, BindingResult result) { log.info("I am verifyValidated() method, the request params is: 【{}】", person); if (result.hasErrors()) { FieldError fieldError = result.getFieldError(); if (fieldError != null) { log.error("error msg: 【{}】", fieldError.getDefaultMessage()); } } } }
-
校验结果
-
@Valid
-
@Validated
-
由上可知,在 @Validated 注解加分组参数的情况下 (@Valid 注解没有分组参数),@Valid 注解只会校验没有添加 groups 属性的实体类字段 (此处只校验了 sex 字段);@Validated 注解只会校验实体类中分组为指定分组的字段,而不会去校验其他字段 (此处只校验了 name 字段)
-
-
四、验证验证排序功能
-
正常在 @Validated 注解不加分组参数的情况下,@Valid 注解和 @Validated 注解会随机校验实体类中不加 groups 属性的字段,不分先后顺序
-
而使用 @GroupSequence 注解则可以使 @Validated 注解在多个分组参数的情况下,具有排序校验功能
-
使用 @GroupSequence 注解
-
分组接口类
@GroupSequence({First.class, Second.class}) public interface Group { }
- 如上所示,我们在 @GroupSequence 注解中指定了校验分组的先后顺序,先校验 First 分组,再校验 Second 分组
-
控制层
@RestController @RequestMapping(value = "/verify") @Slf4j public class VerifyController { @PostMapping(value = "/validated") public void verifyValidated(@Validated(value = Group.class) @RequestBody Person person, BindingResult result) { log.info("I am verifyValidated() method, the request params is: 【{}】", person); if (result.hasErrors()) { FieldError fieldError = result.getFieldError(); if (fieldError != null) { log.error("error msg: 【{}】", fieldError.getDefaultMessage()); } } } }
-
校验结果
-
如下所示,多次调用接口,我们会发现程序始终会先去校验 First 分组 (此处校验了 name 字段),如果该校验不通过,则不会进行后续的校验
-
我们将 json 请求参数改为如下所示,然后再调用接口
{ "name": "Tom", "age": 19, "sex": 10 }
-
-