研究javax.validation.constraints.NotNull運行原理


1. 研究javax.validation.constraints.NotNull運行原理

1.1. 源碼跟進

  1. 為了找到NotNull到底是在哪里被處理,我先打印一個錯誤信息,根據錯誤信息的關鍵字,我首先找到的是這個地方,可以看到是webmvc包,可以理解,畢竟是通過接口請求並攔截的,需要經過webmvc

UTOOLS1587607490936.png

  1. 接下來要探究這句話是怎么產生的了,追溯body值得來源,發現最終捕獲異常的地方在DispatcherServlet類的如下方法,感覺快要找到了,進入handle方法吧

UTOOLS1587608837891.png

  1. 繼續往里面找,找到了拋MethodArgumentNotValidException異常的地方,可以看到驗證參數的方法就是validateIfApplicable

UTOOLS1587609270008.png

  1. 進到這個方法就能看到熟悉的小伙伴了,@Validated這個注解,在需要驗證的Controller接口都需要加,之后的核心驗證方法為binder.validate,之后需要層層遞進分叉非常多了,我就講一條我遇到的實際問題找尋源碼的路徑

UTOOLS1587613176584.png

1.2. 問題

  1. 只是在controller層,寫個@Validated注解,之后的@NotNull判斷等注解判斷只在@Validated定義的對象生效,現在我想要實現對象中的對象也實現驗證效果,我這里直接說結論了,我寫了如下類,我需要body對象也能夠得到參數驗證,則在類方法上加個@Valid注解即可實現,接下去看源碼
@Data
public class Request<T> {
    /**
     * 請求體
     */
    @Valid
    private T body;

    /**
     * 請求碼(預留可不填)
     */
    private Integer requestCode;

    /**
     * 額外請求參數,可另做處理
     */
    private Map<String,Object> extend;
}
  1. 由於深入層數過多,我會挑幾個重點截圖,起到拋磚引玉的作用了,想要深入了解一定要自己看源碼

UTOOLS1587624273122.png

  1. 通過SpringValidatorAdapter驗證類作為核心
    UTOOLS1587624349905.png

  2. 接下去解析注解,中間調整過多,我會跳過幾層

UTOOLS1587624476439.png

UTOOLS1587624659782.png

  1. 終於找到獲取對象屬性的@Valid注解
    UTOOLS1587624723841.png

  2. 獲得了這個級聯元數據,后續的判斷就會用到這個,設值valueContext,我把這個ExampleDeleteVo對象的id屬性設值了注解@NotNull

UTOOLS1587625281444.png

  1. 可以看到它獲取了id為null的值放入了currentValue
    UTOOLS1587625338885.png

UTOOLS1587625547426.png

UTOOLS1587625611470.png

UTOOLS1587625762872.png

1.3. 總結

一開始我研究@Validated注解就是為了找是否有辦法驗證對象內對象,如果不行可能就需要自己寫攔截器方法了,不到迫不得已我也不想重復造輪子,畢竟@Validated自帶的驗證這么多,寫起來也蠻累的,還容易出bug。有耐心看完這篇文章的估計是遇到@Vaildated的問題了,希望能起到拋磚引玉的作用吧


免責聲明!

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



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