Springboot項(xiàng)目參數(shù)校驗(yàn)方式(Validator)
我們使用spring-boot-starter-validation 包+注解的方式來實(shí)現(xiàn)springboot項(xiàng)目中請(qǐng)求參數(shù)校驗(yàn)。其中spring-boot-starter-validation包中依賴了hibernate-validator包,校驗(yàn)功能就是hibernate-validator包所提供的。
一、 pom文件引入依賴
<!--validation校驗(yàn)依賴包 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <!-- <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> -->
引入spring-boot-starter-validation 包后,可以看見包中依賴了hibernate-validator
二、 校驗(yàn)注解列表
下面的注解用于修飾在需要校驗(yàn)的實(shí)體類屬性上方,或者直接用于修飾請(qǐng)求接口的參數(shù)。
注解 | 作用數(shù)據(jù)類型 | 說明 |
---|---|---|
@Null | 任意類型 | 驗(yàn)證注解的元素值是null |
@NotNull | 任意類型 | 驗(yàn)證注解的元素值不是null,無法驗(yàn)證''空串 |
@NotBlank | CharSequence子類型 | 驗(yàn)證注解的元素值不為空(不為null、去除首位空格后長(zhǎng)度為0),不同于@NotEmpty,@NotBlank只應(yīng)用于字符串且在比較時(shí)會(huì)去除字符串的首位空格 |
@NotEmpty | CharSequence子類型、Collection、Map、數(shù)組 | 驗(yàn)證注解的元素值不為null且不為空(字符串長(zhǎng)度不為0、集合大小不為0) |
@Min | 任何Number類型 | 驗(yàn)證注解的元素值大于等于@Min指定的值 |
@Max | 任何Number類型 | 驗(yàn)證注解的元素值小于等于@Max指定的值 |
@DecimalMin | 任何Number類型 | 驗(yàn)證注解的元素值大于等于@ DecimalMin指定的值 |
@DecimalMax | 任何Number類型 | 驗(yàn)證注解的元素值小于等于@ DecimalMax指定的值 |
@Digits(integer=整數(shù)位數(shù), fraction=小數(shù)位數(shù)) | 任何Number類型 | 驗(yàn)證注解的元素值的整數(shù)位數(shù)和小數(shù)位數(shù)上限 |
@Size | 字符串、Collection、Map、數(shù)組等 | 驗(yàn)證注解的元素值的在min和max(包含)指定區(qū)間之內(nèi),如字符長(zhǎng)度、集合大小 |
@Past | Date、Calendar日期類型 | 驗(yàn)證注解的元素值比當(dāng)前時(shí)間早 |
@Future | Date、Calendar日期類型 | 驗(yàn)證注解的元素值比當(dāng)前時(shí)間晚 |
@Length | CharSequence子類型 | 驗(yàn)證注解的元素值長(zhǎng)度在min和max區(qū)間內(nèi) |
@Range | BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子類型和包裝類型 | 驗(yàn)證注解的元素值在最小值和最大值之間 |
@Email(regexp=正則表達(dá)式,flag=標(biāo)志的模式) | CharSequence子類型 | 驗(yàn)證注解的元素值是Email,也可以通過regexp和flag指定自定義的email格式 |
@Pattern(regexp=正則表達(dá)式,flag=標(biāo)志的模式) | CharSequence子類型 | 驗(yàn)證注解的元素值與指定的正則表達(dá)式匹配 |
@Valid | 任何非原子類型 | 指定遞歸驗(yàn)證關(guān)聯(lián)的對(duì)象如用戶對(duì)象中有個(gè)地址對(duì)象屬性,如果想在驗(yàn)證用戶對(duì)象時(shí)一起驗(yàn)證地址對(duì)象的話,在地址對(duì)象上加@Valid注解即可級(jí)聯(lián)驗(yàn)證 |
@AssertFalse | Boolean | 驗(yàn)證注解的元素值是false |
@AssertTrue | Boolean | 驗(yàn)證注解的元素值是true |
三、校驗(yàn)注解用法
1. 注解用于修飾在需要校驗(yàn)的實(shí)體類屬性上方
注解的參數(shù)message 用于自定義校驗(yàn)提示信息。
public class User { @NotNull @Length(min = 2, max = 10, message = "用戶名字必須在2到10個(gè)字母") private String name; @Min(1) @Max(100) private int age; @NotBlank(message = "聯(lián)系郵箱不能為空") @Email(message = "郵箱格式不對(duì)") private String email; @NotBlank(message = "手機(jī)號(hào)不能為空") @Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手機(jī)號(hào)格式有誤") private String mobile; }
然后在請(qǐng)求接口方法參數(shù)上用@Validated或@Valid修飾,不然校驗(yàn)不生效。
@RestController @RequestMapping("/test") public class TestController { @RequestMapping("/01") public Object test01(@Validated User user) { System.out.println("===> user: "+user); return user; } @RequestMapping("/02") public Object test02(@Valid User user) { System.out.println("===> user: "+user); return user; } }
2. 直接用于修飾請(qǐng)求接口的參數(shù)
這種方式需要在接口類上面添加@Validated,不然校驗(yàn)不生效。
@RestController @RequestMapping("/test") @Validated public class TestController { @RequestMapping("/01") public Object test01(@NotNull String name, @Min(1) @Max(100) Integer age) { System.out.println("===> name: "+name+", age="+age); return name; } @RequestMapping("/02") public Object test02(@Email(message = "郵箱格式不對(duì)") String email) { System.out.println("===> email: "+email); return email; }
四、@Validated 與 @Valid的區(qū)別
- @Validated是spring框架下的注解,@Valid注解時(shí)javax包下的注解
- @Validated對(duì)@Valid的封裝,具有更強(qiáng)大的功能,@Validated在@Valid之上提供了分組功能和驗(yàn)證排序功能
- @Valid注解可以用在成員屬性上,提供成員屬性是對(duì)象類型的嵌套校驗(yàn)功能
五、校驗(yàn)失敗的異常捕獲
1. @Validated或@Valid注解的請(qǐng)求參數(shù)后面緊跟一個(gè)BindingResult對(duì)象參數(shù),用于封裝校驗(yàn)異常信息。 注意的是這種方式就不再拋出校驗(yàn)異常了。
@RequestMapping("/01") public Object test01(@Validated User user, BindingResult result) { System.out.println("===> user: "+user); List<ObjectError> allErrors = result.getAllErrors(); if (result.hasErrors()) { allErrors.forEach(item -> { System.out.println(item.getDefaultMessage()); }); } return user; } @RequestMapping("/02") public Object test02(@Valid User user, BindingResult result) { System.out.println("===> user: "+user); List<FieldError> fieldErrors = result.getFieldErrors(); if (result.hasFieldErrors()) { fieldErrors.forEach(item -> { System.out.println(item.getDefaultMessage()); }); } return user; }
2. 使用全局異常類@RestControllerAdvice 捕捉校驗(yàn)失敗的異常
校驗(yàn)失敗會(huì)拋出BindException, ConstraintViolationException, MethodArgumentNotValidException 三種異常
@RestControllerAdvice public class GlobalExceptionHandler { /** * BindException驗(yàn)證異常 */ @ExceptionHandler(BindException.class) public AjaxResult handleBindException(BindException e) { BindingResult bindingResult = e.getBindingResult(); StringBuilder sb = new StringBuilder("校驗(yàn)失敗:"); for (FieldError fieldError : bindingResult.getFieldErrors()) { sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", "); } String msg = sb.toString(); log.error(msg); return AjaxResult.error(msg); } /** * MethodArgumentNotValidException驗(yàn)證異常 */ @ExceptionHandler(MethodArgumentNotValidException.class) public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { BindingResult bindingResult = e.getBindingResult(); StringBuilder sb = new StringBuilder("校驗(yàn)失敗:"); for (FieldError fieldError : bindingResult.getFieldErrors()) { sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", "); } String msg = sb.toString(); log.error(msg); return AjaxResult.error(msg); } /** * ConstraintViolationException異常 */ @ExceptionHandler(ConstraintViolationException.class) public AjaxResult handleConstraintViolationException(ConstraintViolationException e) { log.error(e.getMessage(), e); return AjaxResult.error(e.getMessage()); } }
六、@Validated的分組功能
@Validated具有分組功能, 可以根據(jù)不同的分組采用不同的驗(yàn)證機(jī)制。
1. 自定義group接口并實(shí)現(xiàn)父接口javax.validation.groups.Default
import javax.validation.groups.Default; public interface AddGroup extends Default { } import javax.validation.groups.Default; public interface UpdateGroup extends Default { }
2. 校驗(yàn)注解上提供參數(shù)groups,參數(shù)值就是上面自定義的接口。
public class User { @NotNull @Length(min = 2, max = 10, groups = UpdateGroup.class) private String name; @Min(value = 1, groups = AddGroup.class) @Max(value = 100, groups = AddGroup.class) @NotNull private int age; @NotBlank(message = "聯(lián)系郵箱不能為空", groups = UpdateGroup.class) @Email(message = "郵箱格式不對(duì)", groups = AddGroup.class) private String email; }
3. 給@Validated注解參數(shù)value附上不同的分組類, 這樣校驗(yàn)就會(huì)根據(jù)相同的group類來校驗(yàn)
@RequestMapping("/01") public Object test01(@Validated(value = AddGroup.class) User user, BindingResult result) { System.out.println("===> user: "+user); List<ObjectError> allErrors = result.getAllErrors(); if (result.hasErrors()) { allErrors.forEach(item -> { System.out.println(item.getDefaultMessage()); }); } return user; } @RequestMapping("/02") public Object test02(@Validated(value = UpdateGroup.class) User user, BindingResult result) { System.out.println("===> user: "+user); List<FieldError> fieldErrors = result.getFieldErrors(); if (result.hasFieldErrors()) { fieldErrors.forEach(item -> { System.out.println(item.getDefaultMessage()); }); } return user; }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑
這篇文章主要介紹了解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Java基礎(chǔ)之JDK1.8新特性lambda表達(dá)式詳解
函數(shù)式接口有且僅有一個(gè)抽象方法,但是可以有多個(gè)非抽象方法的接口,函數(shù)式接口可以被隱式轉(zhuǎn)換為lambda表達(dá)式,這篇文章主要介紹了Java基礎(chǔ)之lambda表達(dá)式(JDK1.8新特性),需要的朋友可以參考下2023-08-08使用httpclient無需證書調(diào)用https的示例(java調(diào)用https)
這篇文章主要介紹了使用httpclient無需證書調(diào)用https的示例(java調(diào)用https),需要的朋友可以參考下2014-04-04淺談Java程序運(yùn)行機(jī)制及錯(cuò)誤分析
這篇文章主要主要介紹了Java虛擬機(jī)(JVM)的有關(guān)內(nèi)容以及Java程序的運(yùn)行機(jī)制和錯(cuò)誤分析,需要的朋友可以了解下。2017-09-09Spark學(xué)習(xí)筆記Spark Streaming的使用
這篇文章主要介紹了Spark學(xué)習(xí)筆記Spark Streaming的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法
這篇文章主要介紹了java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08request.getRequestURL()等方法得到路徑的區(qū)別及說明
這篇文章主要介紹了request.getRequestURL()等方法得到路徑的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12