參數(shù)校驗Spring的@Valid注解用法解析
參數(shù)校驗Spring的@Valid注解
@Valid 注解通常用于對象屬性字段的規(guī)則檢測。
以新增一個員工為功能切入點,以常規(guī)寫法為背景,慢慢烘托出 @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 中會有一個對應(yīng)都新增方法 add():
@Controller
public class TestController {
@RequestMapping("/add")
@ResponseBody
public String add(Employee employee) {
// TODO 保存到數(shù)據(jù)庫
return "新增員工成功";
}
}
需求變更,要求員工名稱不能為空,且長度不超過10個字符
我們的原始寫法:

現(xiàn)在規(guī)定年齡也是必填項,且范圍在1到100歲,那么此時,我們需要增加判定

現(xiàn)在員工對象 Employee 就 2 個字段,我們就寫了 10 多行的代碼驗證,要是有20個字段,豈不是要寫 100 多行代碼?
如何解決呢?
將驗證過程抽成一個驗證方法:

但這種方式只是抽了一個方法,有一種換湯不換藥的感覺,雖然業(yè)務(wù)方法看起來清爽了很多,但書寫代碼量并沒有下降,反而還多出了一個方法。
此時引出 Spring 的 @valid 注解即可:
首先,我們在 Maven 配置中引入 @valid 的依賴:
如果你是 springboot 項目,那么可以不用引入了,已經(jīng)引入了,他就存在于最核心的 web 開發(fā)包里面。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
代碼優(yōu)化
首先在 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 對應(yīng)方法上,對這個員工標(biāo)上 @Valid 注解,表示我們對這個對象屬性需要進(jìn)行驗證

用一個東西來存放驗證結(jié)果,做法也很簡單,在參數(shù)直接添加一個BindingResult:

對應(yīng)獲取驗證結(jié)果的代碼如下:

@Valid與@Validated注解
之前項目中參數(shù)的校驗,都是自己寫的判斷方法進(jìn)行校驗,這次采用了spring提供的注解進(jìn)行參數(shù)的校驗,更為的方便,簡潔。
@Valid:常見用在方法,類中字段上進(jìn)行校驗


@Validated:是spring提供的對@Valid的封裝,常見用在方法上進(jìn)行校驗

定義的校驗類型
@Null 驗證對象是否為null
@NotNull 驗證對象是否不為null, 無法查檢長度為0的字符串
@NotBlank 檢查約束字符串是不是Null還有被Trim的長度是否大于0,只對字符串,且會去掉前后空格.
@NotEmpty 檢查約束元素是否為NULL或者是EMPTY.
@CreditCardNumber信用卡驗證
@Email 驗證是否是郵件地址,如果為null,不進(jìn)行驗證,算通過驗證。
@URL(protocol=,host=, port=,regexp=, flags=) ip地址校驗
Booelan檢查
@AssertTrue 驗證 Boolean 對象是否為 true
@AssertFalse 驗證 Boolean 對象是否為 false
長度檢查
@Size(min=, max=) 驗證對象(Array,Collection,Map,String)長度是否在給定的范圍之內(nèi)
@Length(min=, max=) Validates that the annotated string is between min and max included.
日期檢查
@Past 驗證 Date 和 Calendar 對象是否在當(dāng)前時間之前
@Future 驗證 Date 和 Calendar 對象是否在當(dāng)前時間之后
@Pattern 驗證 String 對象是否符合正則表達(dá)式的規(guī)則
數(shù)值檢查,建議使用在Stirng,Integer類型,不建議使用在int類型上,因為表單值為""時無法轉(zhuǎn)換為int,但可以轉(zhuǎn)換為Stirng為"",Integer為null
@Min 驗證 Number 和 String 對象是否大等于指定的值
@Max 驗證 Number 和 String 對象是否小等于指定的值
@DecimalMax 被標(biāo)注的值必須不大于約束中指定的最大值. 這個約束的參數(shù)是一個通過BigDecimal定義的最大值的字符串表示.小數(shù)存在精度
@DecimalMin 被標(biāo)注的值必須不小于約束中指定的最小值. 這個約束的參數(shù)是一個通過BigDecimal定義的最小值的字符串表示.小數(shù)存在精度
@Digits 驗證 Number 和 String 的構(gòu)成是否合法
@Digits(integer=,fraction=) 驗證字符串是否是符合指定格式的數(shù)字,interger指定整數(shù)精度,fraction指定小數(shù)精度。
@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.
注意的幾點:
(1)如果一個bean中包含第二個bean
這時要檢驗第二個bean中某個字段,即嵌套校驗,必須要在第一個bean對象中使用@Valid標(biāo)注到表示第二個bean對象的字段上,然后再第二個bean對象里面的字段上加上校驗類型


(2)@Validated支持分組注解
1、先定義一個空接口:GroupA

2、對bean對象中校驗類型,添加分組信息,這里我對version字段進(jìn)行了分組校驗信息添加

3、方法入?yún)⒅羞M(jìn)行分組信息添加


如上圖所示,則shelveProject方法由于添加了分組信息會校驗DeleteProjectRequest對象中的version字段是否為空,而offShelveProject方法沒有添加分組信息,不會校驗version是否為空。
@Validated沒有添加groups屬性時,默認(rèn)驗證沒有分組的驗證屬性。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java.lang.NullPointerException出現(xiàn)的幾種原因及解決方案
這篇文章主要介紹了java.lang.NullPointerException出現(xiàn)的幾種原因及解決方案,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
java WebSocket客戶端斷線重連的實現(xiàn)方法
在工作中是否會遇到實用websocket客戶端連接服務(wù)端的時候,網(wǎng)絡(luò)波動,服務(wù)端斷連的情況,本文可以直接使用的斷線重連,感興趣的可以了解一下2021-10-10
解讀nextLine().split(“[\\s]“)的意思
這篇文章主要介紹了解讀nextLine().split(“[\\s]“)的意思,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04

