關於BindingResult的使用總結及註意事項

BindingResult總結及註意事項

記一個簡單又好用的API:BindingResult

BindingResult使用起來很簡單,一般在controller中使用

作用:用於對前端穿進來的參數進行校驗,省去瞭大量的邏輯判斷操作

相關的校驗API

空檢查

  • @NotEmpty:用在集合類上面;不能為null,而且長度必須大於0
  • @NotBlank:用在String上面;隻能作用在String上,不能為null,而且調用trim()後,長度必須大於0
  • @NotNull:用在基本類型上;不能為null,但可以為empty。

長度檢查

  • @Size(min=,max=):驗證對象(Array,Collection,Map,String)長度是否在給定的范圍之內 不要錯用瞭異常類型,比如在int上不可用@size
  • @Length(min=, max=):隻適用於String 類型

Booelan檢查

  • @AssertTrue:驗證 Boolean 對象是否為 true
  • @AssertFalse:驗證 Boolean 對象是否為 false

日期檢查

  • @Past:驗證 Date 和 Calendar 對象是否在當前時間之前
  • @Future:驗證 Date 和 Calendar 對象是否在當前時間之後
  • @Pattern:驗證 String 對象是否符合正則表達式的規則

其他驗證

  • @Vaild 遞歸驗證,用於對象、數組和集合,會對對象的元素、數組的元素進行一一校驗
  • @Email 用於驗證一個字符串是否是一個合法的右鍵地址,空字符串或null算驗證通過
  • @URL(protocol=,host=,port=,regexp=,flags=) 用於校驗一個字符串是否是合法URL

數值檢查

建議使用在Stirng,Integer類型,不建議使用在int類型上,因為表單值為”” 時無法轉換為int,但可以轉換為Stirng為””,Integer為null

  • @Min:驗證 Number 和 String 對象是否大等於指定的值
  • @Max:驗證 Number 和 String 對象是否小等於指定的值
  • @DecimalMax:被標註的值必須不大於約束中指定的最大值. 這個約束的參數是一個通過BigDecimal定義的最大值的字符串表示.小數存在精度
  • @DecimalMin:被標註的值必須不小於約束中指定的最小值. 這個約束的參數是一個通過BigDecimal定義的最小值的字符串表示.小數存在精度
  • @Digits:驗證 Number 和 String 的構成是否合法
  • @Digits(integer=,fraction=):驗證字符串是否是符合指定格式的數字,interger指定整數精度,fraction指定小數精度。

項目使用中遇到的問題

一開始傳入的參數沒有使用@Validated 修飾,結果綁定不起作用,參數校驗不成功,加上此註解即可生效。

所以BingdingResult是要與@Validated同時使用的。

項目中具體使用如下:

controller中:

@ApiOperation("添加角色")
@RequestMapping(value = "/create", method = RequestMethod.POST)
@ResponseBody
public CommonResult create(@Validated @RequestBody UmsRole role, BindingResult bindingResult ) {
    int count = roleService.create(role);
    if (count > 0) {
        return CommonResult.success(count);
    }
    return CommonResult.failed();
}

domain中:

import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.Date;
@Data
public class UmsRole implements Serializable {
    private Long id;
    @ApiModelProperty(value = "名稱")
    @NotEmpty(message = "name不能為空!")
    private String name;
    @ApiModelProperty(value = "描述")
    @NotEmpty(message = "描述不能為空!")
    private String description;
    @ApiModelProperty(value = "後臺用戶數量")
    private Integer adminCount;
    @ApiModelProperty(value = "創建時間")
    private Date createTime;
    @ApiModelProperty(value = "啟用狀態:0->禁用;1->啟用")
    private Integer status;
    private Integer sort;
    private static final long serialVersionUID = 1L;

調用接口返回效果:

參數:

{
“name”:“test”
}

返回值:

{
“code”: 404,
“message”: “描述不能為空!”,
“data”: null
}

註意!

1.@Validated 與BindingResult 需要相鄰,否則 變量result 不能接受錯誤信息

控制臺輸出

Field error in object ‘entity’ on field ‘變量’: rejected value [null]; codes [NotNull.entity.變量,NotNull.變量,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes

2.如果使用瞭@Validated,那麼BeanValidate也會拋出異常而不是之前的封裝在BindingResult中

總結:

使用BindingResult,省去瞭代碼塊中的大部分校驗

BindingResult作用原理

controller代碼

@RequestMapping("")
    public String index(@Valid User user , BindingResult bindingResult){
        if (bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            ObjectError objectError = allErrors.get(0);
            System.out.println(objectError.getDefaultMessage());
            System.out.println(objectError.getObjectName());
            System.out.println(allErrors);
        }
        return "index";
    }

請求先來到DispatcherServlet的doDispatch 方法,最終會調用ModelAttributeMethodProcessor#resolveArgument方法

調用DataBinder#validate方法後調用ConstraintTree#validateSingleConstraint,由它來調用具體的驗證器

具體的驗證器

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: