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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM