Spring -- 01 -- @Valid和@Validated注解的区别

原文链接:Spring – 01 – @Valid和@Validated注解的区别


相关文章:


在处理前端页面传来的参数的时候,我们通常会对数据进行校验,从而保证程序的稳定性,这时候我们就会用到 @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
        }
        

        在这里插入图片描述


五、参考资料

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值