解決 Spring 中 針對List內的每個物件的 @Valid 校驗問題

語言: CN / TW / HK

解決 Spring 中 針對List內的每個物件的 @Valid 校驗問題

ApiObjMapList類如下:

public class ApiObjMap {
    private String apiObjMapId;

    @NotBlank(message = "資料來源名稱不能為空!")
    private String dsName;

    @NotBlank(message = "採集型別不能為空!")
    private String collectType;

    @NotEmpty
    private String ourCol;

    @NotEmpty
    private String apiCol;

    private String specificVal;

    private String meaning;

    @NotEmpty
    private String dataType;

    private Date createTime;

    private Date updateTime;
    // 省略 get 和 set
}

1. 使用 ValidList 解決


@Data public class ValidList<E> implements List<E> {

    @Valid
    @Delegate
    private List<E> list = new ArrayList<>();

}

controller變成:


 @RequestMapping(value = "/saveList", method = RequestMethod.POST)
    @ResponseBody
    public R saveList(@RequestBody @Valid ValidList<ApiObjMapList> list) {
    }

丟擲問題:

Information:javac 1.8.0_131 was used to compile java sources Error:(19, 5) java: @Delegate can only use concrete class types, not wildcards, arrays, type variables, or primitives.

這是因為lombok 和 java 1.8 版本的相容有問題,編譯無法通過,該報錯暫時無法解決。

2. 將List<E> 包裝成一個數據物件校驗

包裝方式:


@Data
public class ApiObjMapList {

    @Valid
    List<ApiObjMap> list;
}

controller寫法:


 @RequestMapping(value = "/saveList", method = RequestMethod.POST)
    @ResponseBody
    public R saveList(@RequestBody @Valid ApiObjMapList list) {
    }

json 示例:


{"list":[{"dsName":"test", "collectType":"report1","ourCol":"name", "apiCol":"sName", "dataType":"String"}]}

注意,如果直接傳json array 的話,就像這樣:


[{"dsName":"test", "collectType":"report1","ourCol":"name", "apiCol":"sName", "dataType":"String"}]

會丟擲異常,資訊如下:

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of ApiObjMapList out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of ApiObjMapList out of START_ARRAY token at [Source: (PushbackInputStream); line: 1, column: 1]

至此,我們的問題就解決了,我們可以很愉快的校驗List裡面的物件內容了。

參考

  1. https://stackoverflow.com/questions/28150405/validation-of-a-list-of-objects-in-spring
  2. https://github.com/rzwitserloot/lombok/issues/1935
分享到: