在Controller層有時候需要對接口的輸入參數進行校驗,若是采用自身的校驗邏輯代碼來實現的話,會有一些弊端,一是會分散自己的注意力,不能讓自己專心撰寫業務邏輯代碼;二是會讓校驗邏輯代碼和業務邏輯代碼產生耦合性,代碼體積也比較臃腫。為了規避這種情況,我們可以采用Spring validation的Validated注解來完成接口參數校驗的工作,下面舉實例說明。
(1)PositionDO實體類
public class PositionDO { @NotEmpty private String state; @NotEmpty private String province; @NotEmpty private String city; public PositionDO() { } public PositionDO(@NotEmpty String state, @NotEmpty String province, @NotEmpty String city) { this.state = state; this.province = province; this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "PositionDO{" + "state='" + state + '\'' + ", province='" + province + '\'' + ", city='" + city + '\'' + '}'; } }
此處,@NotEmpty采用默認的錯誤提示,可以通過message方法來提供指定的錯誤信息。
(2)PersonProfileDO實體類
public class PersonProfileDO { @NotEmpty private String id; @NotEmpty private String sex; @NotEmpty private String age; @NotEmpty private String photo; @NotNull private PositionDO positionDo; public PersonProfileDO() { } public PersonProfileDO(@NotEmpty String id, @NotEmpty String sex, @NotEmpty String age, @NotEmpty String photo, @NotNull PositionDO positionDo) { this.id = id; this.sex = sex; this.age = age; this.photo = photo; this.positionDo = positionDo; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getPhoto() { return photo; } public void setPhoto(String photo) { this.photo = photo; } public PositionDO getPositionDo() { return positionDo; } public void setPositionDo(PositionDO positionDo) { this.positionDo = positionDo; } @Override public String toString() { return "PersonProfileDO{" + "id='" + id + '\'' + ", sex='" + sex + '\'' + ", age='" + age + '\'' + ", photo='" + photo + '\'' + ", positionDo=" + positionDo + '}'; } }
此處,@NotEmpty和@NotNull采用默認的錯誤提示,可以通過message方法來提供指定的錯誤信息。
(3)Controller層接口
@ApiOperation(value="設置個人信息", notes="設置個人詳細信息") @RequestMapping(value = "/setProfileInfo", method = RequestMethod.POST) public Map<String, Object> setProfileInfo(@Validated @RequestBody @ApiParam(value="個人詳細信息", required=true)PersonProfileDO personProfileDo, BindingResult bindingResult) { Map<String, Object> map = new HashMap<>(16); if (null != bindingResult && bindingResult.hasErrors()) { List<FieldError> fieldErrorsList = bindingResult.getFieldErrors(); System.out.println("the field error is " + fieldErrorsList); map.put("parameterErrors", fieldErrorsList); } return map; }
這里需要注意了,使用@Validated注解的話,必須要結合BindingResult,否則不會起到自動校驗的作用;BindingResult的作用是存放@Validated校驗不通過的錯誤信息;此外,BindingResult和@Validated位置必須是鄰近的,它們所在的兩個參數必須要靠近,中間不能插入第三着,比如下面這樣的話,就達不到校驗的目的:
setProfileInfo(@Validated @RequestBody @ApiParam(value="個人詳細信息", required=true)PersonProfileDO personProfileDo,
HttpServletRequest httpServletRequest, BindingResult bindingResult)
在上述的示例接口中,由於@Validated和BindingResult之間插入了HttpServletRequest參數,這樣導致@Validated沒有起到有效的檢驗作用。故,@Validate必須和BindingResult綁定使用,並且要遵循就近原則。
(4)校驗效果
通過swagger來測驗,輸入參數內容如下,id的值為空:

接口返回的結果如下:

上圖的紅色框就是字段校驗失敗時的提示信息,目前都是采用默認的消息。
(5)嵌套校驗
在上述例子中,接口的輸入參數PersonProfileDO對象,它若是想對其內部成員PositionDO對象的內部字段進行校驗的話,那么在PersonProfileDO類中還需要這樣處理positionDo成員,如下圖所示:

必須在字段前面添加@Valid注解,注意了這里不能使用@Validated注解,因為它不支持用於字段。
(6)嵌套校驗的輸入參數和校驗結果,如下圖所示:
輸入參數示例:
校驗結果:
到此,Spring的Validation的基本用法已介紹完畢,上述示例可以按部就班地應用到自己的項目中。
