在檢驗(yàn) Controller 的入?yún)⑹欠穹弦?guī)范時(shí), 使用 @Validated 來(lái)校驗(yàn)傳入數(shù)據(jù), 如果數(shù)據(jù)異常則會(huì)統(tǒng)一拋出異常,方便異常中心統(tǒng)一處理
測(cè)試工具可以使用 Postman 個(gè)人感覺(jué)還是很不錯(cuò)的
對(duì)象中添加對(duì)應(yīng)功能注解
@Validated 相關(guān)作用注解標(biāo)簽需要加在 bean 實(shí)體的屬性上
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import java.util.Date;
?
/**
* @ClassName: StudentVO
* @Description: 學(xué)生實(shí)體
* @Author mac
* @Date 2019/6/11 上午10:26
**/
@Data
public class StudentVO {
?
/**
* 姓名
*/
@NotNull(message = "學(xué)生姓名不能為空")
private String name;
?
/**
* 身高
*/
@NotNull(message = "學(xué)生身高不能為空")
private Integer stature;
?
/**
* 體重
*/
@NotNull(message = "學(xué)生體重不能為空")
private Integer weight;
?
/**
* 出生日期
*/
@Past
private Date birth;
嵌套驗(yàn)證
對(duì)于正常業(yè)務(wù)邏輯中的屬性校驗(yàn), 一個(gè)驗(yàn)證注解很可能不能夠滿足需求
比如:在新增學(xué)生信息時(shí), 身高信息不能為空, 同時(shí)也為了防止錄入人員隨便寫身高值, 這個(gè)時(shí)候就需要 嵌套驗(yàn)證
/**
* 身高
* 限制條件 字段值不可為空
* 學(xué)生身高最大值不可超過(guò)299
* 別杠說(shuō)為什么最大不能超過(guò)299 me 愿意
*/
@Max(299)
@NotNull(message = "學(xué)生身高不能為空")
private Integer stature;
在controller中開(kāi)啟驗(yàn)證
在接受參數(shù)前面加上 @Validated 注解, 對(duì)象中的 @NotNull、@Max 等注解才會(huì)生效, 不加的話是無(wú)效的
@PostMapping(value = "save")
public void save(@Validated @RequestBody StudentVO studentVO) {
...
}
@Validated 高級(jí)用法
分組 - groups
舉個(gè)例子, 剛才你在student類中將姓名設(shè)置為了不可為空對(duì)吧, 如果修改的時(shí)候采用同樣的方式來(lái)進(jìn)行驗(yàn)證入?yún)⒛阍趺崔k? 強(qiáng)制給別人改個(gè)名或者把原值傳進(jìn)來(lái)么, 其實(shí)有更優(yōu)雅的方式來(lái)解決這個(gè)問(wèn)題
分組接口類
/**
* @ClassName: Save
* @Description: 驗(yàn)證分組
* @Author mac
* @Date 2019/6/11 下午5:30
**/
public interface Save {
}
實(shí)體類
/**
* 姓名
*/
@NotNull(message = "學(xué)生姓名不能為空", groups = {Save.class})
private String name;
controller
因?yàn)橹挥行彰侄渭尤肓薙ave這個(gè)分組, 如果現(xiàn)在發(fā)起save請(qǐng)求, 只會(huì)驗(yàn)證姓名
@PostMapping(value = "save")
public void save(@Validated({Save.class}) @RequestBody StudentVO studentVO) {
...
}
如果在注解上不加groups, 默認(rèn)每次都會(huì)進(jìn)行驗(yàn)證
可以在一個(gè)注解上添加多個(gè)分組, 只要在 controller中存在一個(gè)就可以驗(yàn)證
只要理解了其實(shí)很通用的, 這里就以文字加以描述了
@Validated({Save.class, Update.class})/** ** 姓名 **/ @NotNull(message = "學(xué)生姓名不能為空", groups = {Save.class, Update.class}) private String name;
分組排序
默認(rèn)情況下, 不同組之間是沒(méi)有順序可言的, 但是在一些特殊場(chǎng)景下是需要進(jìn)行驗(yàn)證依賴的
沒(méi)有遇到過(guò), 就不舉例了
分組接口類 - @GroupSequence
/**
* @ClassName: Save
* @Description: 驗(yàn)證分組
* @Author mac
* @Date 2019/6/11 下午5:30
**/
public interface Save {
?
}
/**
* @ClassName: Update
* @Description: 驗(yàn)證分組
* @Author mac
* @Date 2019/6/11 下午5:47
**/
public interface Update {
}
import javax.validation.GroupSequence;
/**
* @ClassName: Group
* @Description: 分組排序
* @Author mac
* @Date 2019/6/11 下午6:01
**/
@GroupSequence({Save.class, Update.class})
public interface Group {
}
對(duì)象中的注解以及 groups 不變, 將 controller中save方法改下即可
@PostMapping(value = "save")
public void save(@Validated({Group.class}) @RequestBody StudentVO studentVO) {
...
}
附上部分標(biāo)簽含義
| 限制 | 說(shuō)明 |
|---|---|
| @Null | 限制只能為null |
| @NotNull | 限制必須不為null |
| @AssertFalse | 限制必須為false |
| @AssertTrue | 限制必須為true |
| @DecimalMax(value) | 限制必須為一個(gè)不大于指定值的數(shù)字 |
| @DecimalMin(value) | 限制必須為一個(gè)不小于指定值的數(shù)字 |
| @Digits(integer,fraction) | 限制必須為一個(gè)小數(shù),且整數(shù)部分的位數(shù)不能超過(guò)integer,小數(shù)部分的位數(shù)不能超過(guò)fraction |
| @Future | 限制必須是一個(gè)將來(lái)的日期 |
| @Max(value) | 限制必須為一個(gè)不大于指定值的數(shù)字 |
| @Min(value) | 限制必須為一個(gè)不小于指定值的數(shù)字 |
| @Past | 限制必須是一個(gè)過(guò)去的日期 |
| @Pattern(value) | 限制必須符合指定的正則表達(dá)式 |
| @Size(max,min) | 限制字符長(zhǎng)度必須在min到max之間 |
| @Past | 驗(yàn)證注解的元素值(日期類型)比當(dāng)前時(shí)間早 |
| @NotEmpty | 驗(yàn)證注解的元素值不為null且不為空(字符串長(zhǎng)度不為0、集合大小不為0) |
| @NotBlank | 驗(yàn)證注解的元素值不為空(不為null、去除首位空格后長(zhǎng)度為0),不同于@NotEmpty,@NotBlank只應(yīng)用于字符串且在比較時(shí)會(huì)去除字符串的空格 |
| 驗(yàn)證注解的元素值是Email,也可以通過(guò)正則表達(dá)式和flag指定自定義的email格式 |
參考文章
@Valid和@Validated的總結(jié)區(qū)分
springboot中使用@Validated注解對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)