參數驗證 @Validated 和 @Valid 的區別

來源: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 在基本驗證功能上沒有太多區別。可是在分組、註解地方、嵌套驗證等功能上兩個有所不一樣:框架

1. 分組

@Validated:提供了一個分組功能,能夠在入參驗證時,根據不一樣的分組採用不一樣的驗證機制,這個網上也有資料,不詳述。@Valid:做爲標準JSR-303規範,尚未吸取分組的功能。函數

2. 註解地方

@Validated:能夠用在類型、方法和方法參數上。可是不能用在成員屬性(字段)上.net

@Valid:能夠用在方法、構造函數、方法參數和成員屬性(字段)上code

二者是否能用於成員屬性(字段)上直接影響可否提供嵌套驗證的功能。blog

3. 嵌套驗證

在比較二者嵌套驗證時,先說明下什麼叫作嵌套驗證。好比咱們如今有個實體叫作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,便可獲取。

關注公衆號,天天推送一篇乾貨。

相關文章
相關標籤/搜索