zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    C#下如何用NPlot绘制期货股票K线图(3):设计要显示的股票价格图表窗口并定义相应类的成员及函数
    C#下如何用NPlot绘制期货股票K线图(2):读取数据文件让K线图自动更新
    C#下如何用NPlot绘制期货股票K线图(1)?
    freemarker 常见问题
    关于Bootstrap table的回调onLoadSuccess()和onPostBody()使用小结
    mybatis 联表查询
    用mysql存储过程代替递归查询
    MYSQL 级联 添加外键
    IntelliJ Idea 常用快捷键列表
    MySQL大数据量分页查询方法及其优化
  • 原文地址:https://www.cnblogs.com/bytecodebuffer/p/13695361.html
Copyright © 2011-2022 走看看