配置屬性值資料繫結校驗
一、為什麼要對配置屬性值校驗
我們都知道配置檔案是需要開發人員手動來修改的,只要是人為參與就會有出錯的可能。為了避免人為配置出錯的可能,我們需要對配置屬性值做校驗。
比如:
- 針對資料庫密碼配置:需要限定最小長度或者複雜度限制
- 針對系統對外發郵件,郵件傳送方的郵箱地址配置:字串配置要符合一定的郵件正則表示式規則
- 針對某些不能為空的配置:開發人員有可能忘了為它賦值,等等場景
我們不能等到程式上線之後,才發現相關的配置錯誤。所以我們通常對配置屬性與類物件的成員變數繫結的時候,就加上一些校驗規則。如果配置值不符合校驗規則,在應用程式在啟動的時候就會丟擲異常。
二、如何對繫結的屬性值進行校驗
比如:我們希望對之前章節定義的family類裡面爸爸的年齡,進行校驗。讓其不能小於21歲,小於21就是不合理的配置,也就是錯誤配置。那我們該怎麼做呢?
在需要校驗的屬性裝配類上加@Validated註解
@Data
@Component // 必須加入容器內才能讀取配置檔案資訊
@ConfigurationProperties(prefix = "family") //接收yml配置的java實體類,表示配置的整體字首
@Validated
public class Family {
- 校驗父親的年齡,必須大於23歲
public class Father {
private String name;
@Min(23) //最小為23歲
private Integer age;
}
- 校驗familyName,必須不能為空
@NotEmpty
private String familyName;
這些校驗規則註解是在JSR 303(java)規範中定義的,但是JSR 303只是一個規範,並沒有很多比較具體的實現。目前通常都是使用hibernate-validator進行統一引數校驗,hibernate-validator是對JSR 303規範的實現。
所以當你使用註解的時候,如果org.hibernate.validator.constraints包和javax.validation.constraints包同時存在某個校驗註解,要import使用org.hibernate.validator.constraints包。
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
在之前的Spring Boot 版本中,hibernate-validator是作為預設引入的web開發的整合package,但是在我最新使用的Spring Boot 2.3.0.RELEASE已經不是預設引入的了,所以需要通過上面的maven座標單獨引入。
三、當校驗失敗的時候丟擲異常
針對Family的屬性校驗,只需要寫一個測試類,將Family類注入就可以。
@ExtendWith(SpringExtension.class) //Junit5
@SpringBootTest
public class CustomYamlTest {
@Resource
Family family;
@Test
public void hello(){
System.out.println(family.toString());
}
}
如果我們修改family.father.age=18,也就是說不滿足最小值是21的這樣一個校驗規則。
校驗失敗,會有如下異常。
三、其他參考例子:
- @size (min=6, max=20, message="密碼長度只能在6-20之間")
- @pattern (regexp="[a-za-z0-9._%+-]+@[a-za-z0-9.-]+.[a-za-z]{2,4}", message="請輸入正確的郵件格式")
- @Length(min = 5, max = 20, message = "使用者名稱長度必須位於5到20之間")
- @Email(message = "請輸入正確的郵箱")
- @NotNull(message = "使用者名稱稱不能為空")
- @Max(value = 100, message = "年齡不能大於100歲")
- @Min(value= 18 ,message= "必須年滿18歲!" )
- @AssertTrue(message = "bln4 must is true")
- @AssertFalse(message = "blnf must is falase")
- @DecimalMax(value="100",message="decim最大值是100")
- @DecimalMin(value="100",message="decim最小值是100")
- @NotNull(message = "身份證不能為空")
- @Pattern(regexp="^(\d{18,18}|\d{15,15}|(\d{17,17}[x|X]))$", message="身份證格式錯誤")
附錄、常用校驗註解
實際上這些校驗註解不僅可以校驗配置屬性值,也可以校驗HTTP請求引數值,我們後面的章節會為大家再次介紹。
官方JSR 303規範(國外網址,國內訪問比較慢,需要耐心等)
限制 | 說明 |
---|---|
@Null | 限制只能為null |
@NotNull | 限制必須不為null |
@AssertFalse | 限制必須為false |
@AssertTrue | 限制必須為true |
@DecimalMax(value) | 限制必須為一個不大於指定值的數字 |
@DecimalMin(value) | 限制必須為一個不小於指定值的數字 |
@Digits(integer,fraction) | 限制必須為一個小數,且整數部分的位數不能超過integer,小數部分的位數不能超過fraction |
@Future | 限制必須是一個將來的日期 |
@Max(value) | 限制必須為一個不大於指定值的數字 |
@Min(value) | 限制必須為一個不小於指定值的數字 |
@Past | 限制必須是一個過去的日期 |
@Pattern(value) | 限制必須符合指定的正則表示式 |
@Size(max,min) | 限制字元長度必須在min到max之間 |
@Past | 驗證註解的元素值(日期型別)比當前時間早 |
@NotEmpty | 驗證註解的元素值不為null且不為空(字串長度不為0、集合大小不為0) |
@NotBlank | 驗證註解的元素值不為空(不為null、去除首位空格後長度為0),不同於@NotEmpty,@NotBlank只應用於字串且在比較時會去除字串的空格 |
驗證註解的元素值是Email,也可以通過正則表示式和flag指定自定義的email格式 |