來源:blog.csdn.net/qq_27680317/article/details/79970590 整編:Java技術棧(公衆號ID:javastack)java
Spring Validation驗證框架對參數的驗證機制提供了@Validated(Spring's JSR-303 規範,是標準 JSR-303 的一個變種),javax提供了@Valid(標準JSR-303規範),配合 BindingResult 能夠直接提供參數驗證結果。其中對於字段的特定驗證註解好比 @NotNull 等網上處處都有,這裏不詳述app
在檢驗 Controller 的入參是否符合規範時,使用 @Validated 或者 @Valid 在基本驗證功能上沒有太多區別。可是在分組、註解地方、嵌套驗證等功能上兩個有所不一樣:框架
@Validated:提供了一個分組功能,能夠在入參驗證時,根據不一樣的分組採用不一樣的驗證機制,這個網上也有資料,不詳述。@Valid:做爲標準JSR-303規範,尚未吸取分組的功能。函數
@Validated:能夠用在類型、方法和方法參數上。可是不能用在成員屬性(字段)上.net
@Valid:能夠用在方法、構造函數、方法參數和成員屬性(字段)上code
二者是否能用於成員屬性(字段)上直接影響可否提供嵌套驗證的功能。blog
在比較二者嵌套驗證時,先說明下什麼叫作嵌套驗證。好比咱們如今有個實體叫作Item:get
public class Item { @NotNull(message = "id不能爲空") @Min(value = 1, message = "id必須爲正整數") private Long id; @NotNull(message = "props不能爲空") @Size(min = 1, message = "至少要有一個屬性") private List<Prop> props; }
Item帶有不少屬性,屬性裏面有屬性id,屬性值id,屬性名和屬性值,以下所示:it
public class Prop { @NotNull(message = "pid不能爲空") @Min(value = 1, message = "pid必須爲正整數") private Long pid; @NotNull(message = "vid不能爲空") @Min(value = 1, message = "vid必須爲正整數") private Long vid; @NotBlank(message = "pidName不能爲空") private String pidName; @NotBlank(message = "vidName不能爲空") private String vidName; }
屬性這個實體也有本身的驗證機制,好比屬性和屬性值id不能爲空,屬性名和屬性值不能爲空等。io
如今咱們有個 ItemController 接受一個Item的入參,想要對Item進行驗證,以下所示:
@RestController public class ItemController { @RequestMapping("/item/add") public void addItem(@Validated Item item, BindingResult bindingResult) { doSomething(); } }
在上圖中,若是Item實體的props屬性不額外加註釋,只有@NotNull和@Size,不管入參採用@Validated仍是@Valid驗證,Spring Validation框架只會對Item的id和props作非空和數量驗證,不會對props字段裏的Prop實體進行字段驗證,也就是@Validated和@Valid加在方法參數前,都不會自動對參數進行嵌套驗證。也就是說若是傳的List<Prop>中有Prop的pid爲空或者是負數,入參驗證不會檢測出來。
爲了可以進行嵌套驗證,必須手動在Item實體的props字段上明確指出這個字段裏面的實體也要進行驗證。因爲@Validated不能用在成員屬性(字段)上,可是@Valid能加在成員屬性(字段)上,並且@Valid類註解上也說明了它支持嵌套驗證功能,那麼咱們可以推斷出:@Valid加在方法參數時並不可以自動進行嵌套驗證,而是用在須要嵌套驗證類的相應字段上,來配合方法參數上@Validated或@Valid來進行嵌套驗證。
咱們修改Item類以下所示:
public class Item { @NotNull(message = "id不能爲空") @Min(value = 1, message = "id必須爲正整數") private Long id; @Valid // 嵌套驗證必須用@Valid @NotNull(message = "props不能爲空") @Size(min = 1, message = "props至少要有一個自定義屬性") private List<Prop> props; }
而後咱們在ItemController的addItem函數上再使用@Validated或者@Valid,就能對Item的入參進行嵌套驗證。此時Item裏面的props若是含有Prop的相應字段爲空的狀況,Spring Validation框架就會檢測出來,bindingResult就會記錄相應的錯誤。
總結一下 @Validated 和 @Valid 在嵌套驗證功能上的區別:
@Validated: 用在方法入參上沒法單獨提供嵌套驗證功能。不能用在成員屬性(字段)上,也沒法提示框架進行嵌套驗證。能配合嵌套驗證註解@Valid進行嵌套驗證。
@Valid: 用在方法入參上沒法單獨提供嵌套驗證功能。可以用在成員屬性(字段)上,提示驗證框架進行嵌套驗證。能配合嵌套驗證註解@Valid進行嵌套驗證。
另外,棧長已經整理了 Java 系列核心知識點文章,關注Java技術棧公衆號,在後臺回覆關鍵字:java,便可獲取。
關注公衆號,天天推送一篇乾貨。