Springboot項(xiàng)目參數(shù)校驗(yàn)方式(Validator)
我們使用spring-boot-starter-validation 包+注解的方式來(lái)實(shí)現(xiàn)springboot項(xiàng)目中請(qǐng)求參數(shù)校驗(yàn)。其中spring-boot-starter-validation包中依賴(lài)了hibernate-validator包,校驗(yàn)功能就是hibernate-validator包所提供的。
一、 pom文件引入依賴(lài)
<!--validation校驗(yàn)依賴(lài)包 -->
<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 包后,可以看見(jiàn)包中依賴(lài)了hibernate-validator

二、 校驗(yàn)注解列表
下面的注解用于修飾在需要校驗(yàn)的實(shí)體類(lèi)屬性上方,或者直接用于修飾請(qǐng)求接口的參數(shù)。
| 注解 | 作用數(shù)據(jù)類(lèi)型 | 說(shuō)明 |
|---|---|---|
| @Null | 任意類(lèi)型 | 驗(yàn)證注解的元素值是null |
| @NotNull | 任意類(lèi)型 | 驗(yàn)證注解的元素值不是null,無(wú)法驗(yàn)證''空串 |
| @NotBlank | CharSequence子類(lèi)型 | 驗(yàn)證注解的元素值不為空(不為null、去除首位空格后長(zhǎng)度為0),不同于@NotEmpty,@NotBlank只應(yīng)用于字符串且在比較時(shí)會(huì)去除字符串的首位空格 |
| @NotEmpty | CharSequence子類(lèi)型、Collection、Map、數(shù)組 | 驗(yàn)證注解的元素值不為null且不為空(字符串長(zhǎng)度不為0、集合大小不為0) |
| @Min | 任何Number類(lèi)型 | 驗(yàn)證注解的元素值大于等于@Min指定的值 |
| @Max | 任何Number類(lèi)型 | 驗(yàn)證注解的元素值小于等于@Max指定的值 |
| @DecimalMin | 任何Number類(lèi)型 | 驗(yàn)證注解的元素值大于等于@ DecimalMin指定的值 |
| @DecimalMax | 任何Number類(lèi)型 | 驗(yàn)證注解的元素值小于等于@ DecimalMax指定的值 |
| @Digits(integer=整數(shù)位數(shù), fraction=小數(shù)位數(shù)) | 任何Number類(lèi)型 | 驗(yàn)證注解的元素值的整數(shù)位數(shù)和小數(shù)位數(shù)上限 |
| @Size | 字符串、Collection、Map、數(shù)組等 | 驗(yàn)證注解的元素值的在min和max(包含)指定區(qū)間之內(nèi),如字符長(zhǎng)度、集合大小 |
| @Past | Date、Calendar日期類(lèi)型 | 驗(yàn)證注解的元素值比當(dāng)前時(shí)間早 |
| @Future | Date、Calendar日期類(lèi)型 | 驗(yàn)證注解的元素值比當(dāng)前時(shí)間晚 |
| @Length | CharSequence子類(lèi)型 | 驗(yàn)證注解的元素值長(zhǎng)度在min和max區(qū)間內(nèi) |
| @Range | BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子類(lèi)型和包裝類(lèi)型 | 驗(yàn)證注解的元素值在最小值和最大值之間 |
| @Email(regexp=正則表達(dá)式,flag=標(biāo)志的模式) | CharSequence子類(lèi)型 | 驗(yàn)證注解的元素值是Email,也可以通過(guò)regexp和flag指定自定義的email格式 |
| @Pattern(regexp=正則表達(dá)式,flag=標(biāo)志的模式) | CharSequence子類(lèi)型 | 驗(yàn)證注解的元素值與指定的正則表達(dá)式匹配 |
| @Valid | 任何非原子類(lèi)型 | 指定遞歸驗(yàn)證關(guān)聯(lián)的對(duì)象如用戶(hù)對(duì)象中有個(gè)地址對(duì)象屬性,如果想在驗(yàn)證用戶(hù)對(duì)象時(shí)一起驗(yàn)證地址對(duì)象的話(huà),在地址對(duì)象上加@Valid注解即可級(jí)聯(lián)驗(yàn)證 |
| @AssertFalse | Boolean | 驗(yàn)證注解的元素值是false |
| @AssertTrue | Boolean | 驗(yàn)證注解的元素值是true |

三、校驗(yàn)注解用法
1. 注解用于修飾在需要校驗(yàn)的實(shí)體類(lèi)屬性上方
注解的參數(shù)message 用于自定義校驗(yàn)提示信息。
public class User {
@NotNull
@Length(min = 2, max = 10, message = "用戶(hù)名字必須在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ù)
這種方式需要在接口類(lèi)上面添加@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ì)象類(lèi)型的嵌套校驗(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. 使用全局異常類(lèi)@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附上不同的分組類(lèi), 這樣校驗(yàn)就會(huì)根據(jù)相同的group類(lèi)來(lái)校驗(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)文章
Java語(yǔ)言實(shí)現(xiàn)掃雷游戲(2)
這篇文章主要為大家詳細(xì)介紹了Java語(yǔ)言實(shí)現(xiàn)掃雷游戲第二部分代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解決
原來(lái)win10電腦上安裝的是jdk8的版本,因某些原因,現(xiàn)在想換成jdk7的版本,修改環(huán)境變量后,在cmd中執(zhí)行 [java -version]命令,顯示的是7的版本,遇到這樣的問(wèn)題如何解決呢?下面小編給大家分享IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解決方案,一起看看吧2023-09-09
SpringBoot參數(shù)校驗(yàn)之@Valid與@Validated的用法與場(chǎng)景
這篇文章主要介紹了SpringBoot參數(shù)校驗(yàn)的用法與場(chǎng)景,在實(shí)際開(kāi)發(fā)中,參數(shù)校驗(yàn)是保證接口安全性和數(shù)據(jù)完整性的重要手段,Spring Boot提供了@Valid和@Validated兩個(gè)核心注解來(lái)實(shí)現(xiàn)參數(shù)校驗(yàn),但許多開(kāi)發(fā)者對(duì)它們的區(qū)別和使用場(chǎng)景存在疑惑,需要的朋友可以參考下2025-02-02
Java實(shí)現(xiàn)輕松處理日期和時(shí)間的API小結(jié)
這篇文章主要為大家詳細(xì)介紹了Java中的日期和時(shí)間API,可以輕松處理日期和時(shí)間,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
Java設(shè)計(jì)模式之java狀態(tài)模式詳解
這篇文章主要介紹了Java設(shè)計(jì)模式之狀態(tài)模式定義與用法,結(jié)合具體實(shí)例形式詳細(xì)分析了Java狀態(tài)模式的概念、原理、定義及相關(guān)操作技巧,需要的朋友可以參考下2021-09-09
搭建MyBatis-Plus框架并進(jìn)行數(shù)據(jù)庫(kù)增刪改查功能
這篇文章主要介紹了搭建MyBatis-Plus框架并進(jìn)行數(shù)據(jù)庫(kù)增刪改查,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
java多線(xiàn)程創(chuàng)建及線(xiàn)程安全詳解
多線(xiàn)程是日常開(kāi)發(fā)中的常用知識(shí),也是難用知識(shí)。通這篇文章主要給大家介紹了關(guān)于java多線(xiàn)程創(chuàng)建及線(xiàn)程安全的相關(guān)資料,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
基于SpringBoot bootstrap.yml配置未生效的解決

