• springboot 校验机制 @Validated @Valid


    一、探究原因

    在开发的过程中一直迷惑 @Validated 与 @Valid 的用法,有时候是@Validated ,有时候是@Valid  。虽然能够实现校验,但是还是不够明确何时能够生效,不了解他生效的情况

    首先定位2个注解所属的包:

    @Validated  在 spring-context 包下属于spring 提供的核心包

    @Valid 在 validation-api 包下  2.0.2 版本

    @Validated 是spring 核心包,是每个项目都有的,那么 api 是如何引入的? 查看maven 依赖

     原来是在引入 Spring-boot-start-web 的时候,就引入了该依赖

    两个注解存在不同的包,而@NotNull ,@Null ,@Size ,@Max 等校验注解是哪里的呢?

     这些注解都是在 api 包下

    二、使用@Validated 实现校验机制

    情景一: 查询参数是一个实体,Get 请求,在不添加任何注解的情况下,查询是正常的,实体参数字段都为null 

     现在需求 id  字段不能为空,在实体id 字段标记 @NotNull ,继续查询,发现注解没有生效

    经过测试,只有请求实体参数列表前加@Validated 才会生效,即使@Validated 加在类上也无法生效

    情景二: 查询参数是基本或者引用类型字段,参数列表中加入 @NutNull 修改该字段。发现无法生效

    经过测试:只有全局类上加@Validated 才会生效,即使参数列表中加入 @Validated 也无法生效

    产生异常也有所不同:在校验生效的情况下,实体类校验产生的异常是:BindException , 而参数列表产生的异常是: ConstraintViolationException

    三、使用@Valid 实现校验机制

    场景一:与上述一致,只有@Valid 作用在参数列表前才会生效

    场景二:@Valida 不管是左右在参数列表还是类上,都无法生效。只能使用@Validated 全局设置

    结论:暂不清楚@Valid 设计出现的原因,所以的校验@Validate 均可以实现

    附加全局异常捕获:

     1 @RestControllerAdvice
     2 public class GlobalException {
     3 
     4 
     5     @ExceptionHandler({BindException.class})
     6     public RespResult validationException(BindException exception){
     7         List<ObjectError> errors =  exception.getAllErrors();
     8         if(!CollectionUtils.isEmpty(errors)){
     9             StringBuilder sb = new StringBuilder();
    10             errors.forEach(e->sb.append(e.getDefaultMessage()).append(","));
    11             return new RespResult(400, sb.toString());
    12         }
    13         return new RespResult(500, exception.getLocalizedMessage());
    14     }
    15 
    16     @ExceptionHandler({ConstraintViolationException.class})
    17     public RespResult constraintViolationException(ConstraintViolationException exception){
    18         Set<ConstraintViolation<?>> constraintViolations = exception.getConstraintViolations();
    19         if(!CollectionUtils.isEmpty(constraintViolations)){
    20             StringBuilder sb = new StringBuilder();
    21             constraintViolations.forEach(e->sb.append(e.getMessage()).append(","));
    22             return new RespResult(400, sb.toString());
    23         }
    24         return new RespResult(500, exception.getLocalizedMessage());
    25     }
    26 
    27 }
  • 相关阅读:
    vue-cli3.0配置开发环境,测试环境,线上环境
    jQuery使用CDN加速
    浏览器中JavaScript脚本代码的load、ready等方法的加载顺序
    使用 JavaScript 拦截和跟踪浏览器中的 HTTP 请求
    Node和NPM在Windows环境下绿色安装及配置
    Nodejs 中将html转换成pdf文件
    数学励志公式:每天进步一点点
    网页调用打印机打印时纸张A4的设置
    用JS或jQuery访问页面内的iframe,兼容IE/FF
    HTML to DOM
  • 原文地址:https://www.cnblogs.com/bytecodebuffer/p/13695361.html
Copyright © 2020-2023  润新知