參數校驗Spring的@Valid註解用法解析
參數校驗Spring的@Valid註解
@Valid 註解通常用於對象屬性字段的規則檢測。
以新增一個員工為功能切入點,以常規寫法為背景,慢慢烘托出 @Valid 註解用法詳解。
那麼,首先,我們會有一個員工對象 Employee,如下 :
public class Employee { /** 姓名 */ public String name; /** 年齡 */ public Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
然後 Cotroller 中會有一個對應都新增方法 add():
@Controller public class TestController { @RequestMapping("/add") @ResponseBody public String add(Employee employee) { // TODO 保存到數據庫 return "新增員工成功"; } }
需求變更,要求員工名稱不能為空,且長度不超過10個字符
我們的原始寫法:
現在規定年齡也是必填項,且范圍在1到100歲,那麼此時,我們需要增加判定
現在員工對象 Employee 就 2 個字段,我們就寫瞭 10 多行的代碼驗證,要是有20個字段,豈不是要寫 100 多行代碼?
如何解決呢?
將驗證過程抽成一個驗證方法:
但這種方式隻是抽瞭一個方法,有一種換湯不換藥的感覺,雖然業務方法看起來清爽瞭很多,但書寫代碼量並沒有下降,反而還多出瞭一個方法。
此時引出 Spring 的 @valid 註解即可:
首先,我們在 Maven 配置中引入 @valid 的依賴:
如果你是 springboot 項目,那麼可以不用引入瞭,已經引入瞭,他就存在於最核心的 web 開發包裡面。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.5.RELEASE</version> </dependency>
代碼優化
首先在 Employee 類的屬性上打上如下註解:
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Range; public class Employee { /** 姓名 */ @NotBlank(message = "請輸入名稱") @Length(message = "名稱不能超過個 {max} 字符", max = 10) public String name; /** 年齡 */ @NotNull(message = "請輸入年齡") @Range(message = "年齡范圍為 {min} 到 {max} 之間", min = 1, max = 100) public Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
然後再 Controller 對應方法上,對這個員工標上 @Valid 註解,表示我們對這個對象屬性需要進行驗證
用一個東西來存放驗證結果,做法也很簡單,在參數直接添加一個BindingResult:
對應獲取驗證結果的代碼如下:
@Valid與@Validated註解
之前項目中參數的校驗,都是自己寫的判斷方法進行校驗,這次采用瞭spring提供的註解進行參數的校驗,更為的方便,簡潔。
@Valid:常見用在方法,類中字段上進行校驗
@Validated:是spring提供的對@Valid的封裝,常見用在方法上進行校驗
定義的校驗類型
@Null
驗證對象是否為null
@NotNull
驗證對象是否不為null, 無法查檢長度為0的字符串
@NotBlank
檢查約束字符串是不是Null還有被Trim的長度是否大於0,隻對字符串,且會去掉前後空格.
@NotEmpty
檢查約束元素是否為NULL或者是EMPTY.
@CreditCardNumber
信用卡驗證
@Email
驗證是否是郵件地址,如果為null,不進行驗證,算通過驗證。
@URL
(protocol=,host=, port=,regexp=, flags=) ip地址校驗
Booelan檢查
@AssertTrue
驗證 Boolean 對象是否為 true
@AssertFalse
驗證 Boolean 對象是否為 false
長度檢查
@Size(min=, max=)
驗證對象(Array,Collection,Map,String)長度是否在給定的范圍之內
@Length(min=, max=) Validates that the annotated string is between min and max included.
日期檢查
@Past
驗證 Date 和 Calendar 對象是否在當前時間之前
@Future
驗證 Date 和 Calendar 對象是否在當前時間之後
@Pattern
驗證 String 對象是否符合正則表達式的規則
數值檢查,建議使用在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指定小數精度。
@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.
註意的幾點:
(1)如果一個bean中包含第二個bean
這時要檢驗第二個bean中某個字段,即嵌套校驗,必須要在第一個bean對象中使用@Valid標註到表示第二個bean對象的字段上,然後再第二個bean對象裡面的字段上加上校驗類型
(2)@Validated支持分組註解
1、先定義一個空接口:GroupA
2、對bean對象中校驗類型,添加分組信息,這裡我對version字段進行瞭分組校驗信息添加
3、方法入參中進行分組信息添加
如上圖所示,則shelveProject方法由於添加瞭分組信息會校驗DeleteProjectRequest對象中的version字段是否為空,而offShelveProject方法沒有添加分組信息,不會校驗version是否為空。
@Validated沒有添加groups屬性時,默認驗證沒有分組的驗證屬性。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 詳解Spring中@Valid和@Validated註解用法
- 解決get請求入參@NotNull驗證不生效問題
- 如何解決@NotBlank不生效的問題
- springmvc項目使用@Valid+BindingResult遇到的問題
- spring validation多層對象校驗教程