SpringBoot Validator數(shù)據(jù)校驗(yàn)

什么是數(shù)據(jù)校驗(yàn)?
Spring-boot-starter-validation可以用來(lái)校驗(yàn)SpringMVC的入?yún)?,也就是可以用?lái)校驗(yàn)參數(shù)的合理性。
在數(shù)據(jù)校驗(yàn)中,如果傳遞的參數(shù)不滿足要求,或者未傳遞參數(shù),后臺(tái)服務(wù)接口拒絕請(qǐng)求,并返回400錯(cuò)誤,一個(gè)糟糕的請(qǐng)求。
這就很方便的處理了數(shù)據(jù)校驗(yàn)。
提示:
Spring Boot 的Validator數(shù)據(jù)校驗(yàn)實(shí)際上使用的是Hibrenate的Validator數(shù)據(jù)校驗(yàn)。
測(cè)試代碼:
/**
?*?控制層Controller
?*?@Author?黃柏茗
?*?@Date?2021-12-14
?*/
@RestController
@RequestMapping("/test")
public?class?UserController?{
????@RequestMapping("/saveUser")
????public?User?saveUser(?User?user)?{
????????//保存信息
????????System.out.println("用戶信息保存成功!");
????????return?user;
????}
}測(cè)試訪問(wèn):(未輸入數(shù)據(jù))
|
使用validation數(shù)據(jù)校驗(yàn)
校驗(yàn)入?yún)⒌暮侠硇?,和合法性?br>
1.引入依賴:
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-validationartifactId>
????????dependency>2.在實(shí)體屬性上添加校驗(yàn)注解
public?class?User?{
????private?int?id;
????@NotBlank(message?=?"用戶名不能為空")
????private?String?userName;
????
????@NotBlank(message?=?"密碼不能為空")
????@Length(min?=?2,max?=?20,message?=?"密碼長(zhǎng)度在2-20之間")
????private?String??password;
????@NotBlank(message?=?"郵箱不能為空")
????@Email(message?=?"郵箱格式不合理")
????private?String?email;
}被加上注解的屬性,會(huì)在MVC入?yún)r(shí)進(jìn)行數(shù)據(jù)校驗(yàn),如不合理,則返回400錯(cuò)誤,并在后臺(tái)輸出錯(cuò)誤信息。
3.在方法上加上 @Valid 或者?@Validated 注解:

測(cè)試:(未輸入數(shù)據(jù))
|
后臺(tái)輸出
|
訪問(wèn):(輸入合法參數(shù))
localhost:8080/test/saveUser?userName=黃柏茗[email protected]
|
簡(jiǎn)單的使用過(guò)程就是這了。
validation常用校驗(yàn)注解
1.JSR提供的校驗(yàn)注解:
@Null???被注釋的元素必須為null???
@NotNull????被注釋的元素必須不為null???
@AssertTrue?????被注釋的元素必須為true???
@AssertFalse????被注釋的元素必須為false???
@Min(value)?????被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值???
@Max(value)?????被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值???
@DecimalMin(value)??被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值???
@DecimalMax(value)??被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值???
@Size(max=,min=)???被注釋的元素的大小必須在指定的范圍內(nèi)???
@Digits(integer,?fraction)?????被注釋的元素必須是一個(gè)數(shù)字,其值必須在可接受的范圍內(nèi)???
@Past???被注釋的元素必須是一個(gè)過(guò)去的日期???
@Future?????被注釋的元素必須是一個(gè)將來(lái)的日期???
@Pattern(regex=,flag=)??被注釋的元素必須符合指定的正則表達(dá)式???2.Hibernate Validation提供的校驗(yàn)注解
@NotBlank(message=)???驗(yàn)證字符串非null,且trim后長(zhǎng)度必須大于0???
@Email??被注釋的元素必須是電子郵箱地址???
@Length(min=,max=)??被注釋的字符串的大小必須在指定的范圍內(nèi)???
@NotEmpty???被注釋的字符串的必須非空???
@Range(min=,max=,message=)??被注釋的元素必須在合適的范圍內(nèi)舉個(gè)例子奧
1. 姓名長(zhǎng)度必須在2-20之間
@NotNull(message?=?"姓名不能為空")
@Size(min?=?2,?max?=?20,?message?=?"姓名長(zhǎng)度必須在1-20之間")
private?String?name;2. 年齡需要在10-30之間
@Min(value?=?10,?message?=?"年齡必須大于10")
@Max(value?=?150,?message?=?"年齡必須小于30")
private?Integer?age;3. 郵箱格式校驗(yàn)
@NotBlank(message?=?"郵箱不能為空")
@Email(message?=?"郵箱格式不合理")
private?String?email;4.?自定義郵箱正則表達(dá)式
@Email(regexp?=?"^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$",message?=?"郵箱格式不合理")
private?String?email;
5.手機(jī)號(hào)格式校驗(yàn)
@Pattern(regexp?=?"^1(3|4|5|7|8)\\d{9}$",message?=?"手機(jī)號(hào)碼格式錯(cuò)誤")
@NotBlank(message?=?"手機(jī)號(hào)碼不能為空")
private?String?phone;進(jìn)階使用
1.有無(wú) @NotBlank的區(qū)別
代碼一:
private String password;
代碼二:
private?String?password
這兩段代碼的區(qū)別是屬性上是否有?@NotBlank 注解。
結(jié)果也是有區(qū)別的
訪問(wèn):
//注意,沒(méi)輸入密碼參數(shù)奧localhost:8080/test/saveUser?userName=黃柏茗[email protected]
代碼一正常訪問(wèn)。
代碼二提示密碼不能為空。
也就是代碼一:入?yún)assword可以不帶,會(huì)進(jìn)行長(zhǎng)度校驗(yàn),可以正常訪問(wèn)。
代碼二:入?yún)⒈仨毺顚?xiě),填寫(xiě)的規(guī)則必須滿足要求。
簡(jiǎn)單理解:
沒(méi)有注解,可以正常訪問(wèn),有注解就要傳遞入?yún)ⅰ?br>
2.單個(gè)參數(shù)校驗(yàn)
在方法中如果是單個(gè)參數(shù),也可以校驗(yàn)。
需要在類上添加 @Validated 注解,否則不會(huì)生效。
也成參數(shù)平鋪。
import?com.hbm.example.boottestvalidation.pojo.User;
import?org.hibernate.validator.constraints.NotBlank;
import?org.springframework.validation.annotation.Validated;
import?org.springframework.web.bind.annotation.RequestMapping;
import?org.springframework.web.bind.annotation.RestController;
/**
?*?控制層Controller
?*
?*?@Author?黃柏茗
?*?@Date?2021-12-14
?*/
@RestController
@RequestMapping("/test")
@Validated?//用于支持方法的單參數(shù)校驗(yàn)
public?class?UserController?{
????@RequestMapping("/test2")
????public?String?test2(@NotBlank(message?=?"需要參數(shù)name")?String?name)?{
????????//保存信息
????????System.out.println("你輸入的是:"+name);
????????return?name;
????}
}
當(dāng)參數(shù)平鋪到方法入?yún)⒅袝r(shí),在這種情況下,必須在Controller類上標(biāo)注?@Validated?注解,并在入?yún)⑸下暶骷s束注解(如@Min等,你需要的校驗(yàn)注解)。
3.校驗(yàn)?zāi)J?/strong>
默認(rèn)的校驗(yàn)?zāi)J綖槠胀J?,一次性返回了所有?yàn)證不通過(guò)的集合(控制臺(tái)打?。?/p>
通常按順序驗(yàn)證到第一個(gè)字段不符合驗(yàn)證要求時(shí),就可以直接拒絕請(qǐng)求了。
Hibernate Validateor有以下2種驗(yàn)證模式:
普通模式(默認(rèn))
會(huì)校驗(yàn)完所有的屬性,然后返回所有的驗(yàn)證失敗的信息。
快速失敗返回模式
只要一個(gè)驗(yàn)證失敗,則返回驗(yàn)證失敗,拒絕請(qǐng)求,
配置快速返回失敗模式:
????@Bean
????public?LocalValidatorFactoryBean?getValidatorFactory(){
????????LocalValidatorFactoryBean?localValidatorFactoryBean?=?new?LocalValidatorFactoryBean();
????????localValidatorFactoryBean.getValidationPropertyMap().put("hibernate.validator.fail_fast","true");
????????System.out.println("已配置快速失敗返回模式");
????????return?localValidatorFactoryBean;
????}此方法交給Ioc容器進(jìn)行管理即可,自動(dòng)開(kāi)啟快速返回模式。
只要傳入的一個(gè)參數(shù)不合理,就直接
在驗(yàn)證未通過(guò)驗(yàn)證后,會(huì)直接返回400錯(cuò)誤,一個(gè)壞的請(qǐng)求。
4.異常獨(dú)自處理
我們需要在方法里定義 BindingResult 對(duì)象,該對(duì)象用于檢測(cè)該方法內(nèi)是否發(fā)生異常,如果發(fā)生異常,可以在里面處理異常,保證服務(wù)正常合理。
也就是說(shuō),如果發(fā)生異常,不想直接拋出,可以添加?BindingResult?參數(shù)。
????/**
?????*?測(cè)試保存用戶
?????*?@param?user ?????????入?yún)?duì)象
?????*?@param?bindingResult?綁定結(jié)果對(duì)象(可用判斷異常是否出現(xiàn))
?????*?@return
?????*/
????@RequestMapping("/saveUser")
????public?User?saveUser(@Validated?User?user,?BindingResult?bindingResult)?{
????????//如果發(fā)生異常,則可以獨(dú)自處理
????????if?(bindingResult.hasErrors())?{
????????????System.err.println("有異常信息");
????????????for?(ObjectError?error?:?bindingResult.getAllErrors())?{
????????????????//打印異常信息
????????????????System.out.println(error.getDefaultMessage());
????????????}
????????????//在此處可以處理異常,隨意發(fā)揮,在這里我返回null
????????????return?null;
????????}
????????//保存信息,進(jìn)入業(yè)務(wù)代碼
????????System.out.println("業(yè)務(wù)完成,用戶信息保存成功!");
????????return?user;
????}
如果傳入?yún)?shù)有異常,就在這里處理,沒(méi)有異常,則進(jìn)入業(yè)務(wù)代碼。
提示:
Springboot版本小于2.3.x,自動(dòng)包含spring-boot-starter-web會(huì)自動(dòng)傳入hibernate-validator依賴。
Springboot版本大于2.3.x,需要手動(dòng)導(dǎo)入依賴。
總結(jié):
校驗(yàn)MVC的入?yún)⑹欠窈侠磉€是挺方便的,可以減少大量的 if 判斷。
配合使用獨(dú)自處理異常,還是很OK的。




