Spring-Validation 后端數(shù)據(jù)校驗的實現(xiàn)
前言
最近看到很多童鞋在項目中的對請求參數(shù)的校驗都用的if來判斷各參數(shù)的屬性,如:
if(StringUtils.isBlank(username)){
return RR.exception("賬號不能為空");
}
if(StringUtils.isBlank(password)){
return RR.exception("密碼不能為空");
}
if(StringUtils.isBlank(realName)){
return RR.exception("姓名不能為空");
}
......
每個參數(shù)都需要這樣一個個去校驗null,返回對應(yīng)信息,代碼就像疊羅漢一樣~~,在此,樓主強烈推薦一個神器:Validation,有了它,再也不用這樣去校驗參數(shù)啦,可以讓我們在項目中不用太關(guān)注其他東西,專注于業(yè)務(wù)邏輯的編寫。
引入核心依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
使用示例-添加用戶
需要校驗的實體類,在此使用了一些常用的校驗注解,基本上能夠見名知意,每個注解中都有message屬性,就是校驗不通過后的提示信息
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "Account", description = "用戶實體類")
public class Account implements Serializable {
private static final long serialVersionUID = -6310331730721778951L;
private Long id;
@NotBlank(message = "用戶名不能為空")
@Length(max = 10, message = "用戶名最長為10位")
private String name;
@Pattern(regexp = PatternUtil.PASSWORDREGEX, message = "密碼為6-20位數(shù)字加字母組合")
private String pwd;
@NotBlank(message = "姓名不能為空")
@Length(max = 8, message = "姓名最長為8位")
private String realName;
@Pattern(regexp = PatternUtil.PHONENOREGEX, message = "手機號碼格式不正確")
private String phone;
@NotNull(message = "用戶性別不能為空")
@Max(value = 1,message = "性別 0:男 1:女")
@Min(value = 0,message = "性別 0:男 1:女")
private Integer sex;
@NotNull(message = "用戶狀態(tài)不能為空")
@Max(value = 1,message = "用戶狀態(tài) 0:啟用 1:禁用")
@Min(value = 0,message = "用戶狀態(tài) 0:啟用 1:禁用")
private Integer status;
@Length(max = 200, message = "備注最長為200個字符")
private String rmk;
}
controller接口,注意在接收參數(shù)前需加上@Validated注解,這樣就會逐個去校驗實體類中需要加了校驗注解的的屬性,完全通過才進入下一步業(yè)務(wù)處理,否則拋出MethodArgumentNotValidException異常,在這里我們直接將異常拋出,交給全局異常處理類來處理。
@SysLog(menu = "用戶管理", function = "添加",filterParams = {"pwd","password","salt"})
@PermissionCheck("account:manager:add")
@PostMapping(value = "/add", produces = BaseConsts.REQUEST_HEADERS_CONTENT_TYPE)
@ApiOperation(value = "用戶管理-添加用戶接口", notes = "用戶管理-添加用戶接口", httpMethod = BaseConsts.REQUEST_METHOD, response = RR.class)
public RR add(@Validated @RequestBody Account account) throws Exception {
return RR.success("添加用戶成功");
}
聲明全局異常處理類,處理所有異常,可以隨業(yè)務(wù)需要將異常種類細分,返回錯誤碼,返回提示信息可自由定義... 這里只需關(guān)注MethodArgumentNotValidException異常。
@RestControllerAdvice
public class GlobalExceptionHandle {
/**
* @param e
* @return
* @Description 未知異常處理
*/
@ExceptionHandler(Exception.class)
public RR handleException(Exception e) {
e.printStackTrace();
return RR.exception("系統(tǒng)異常,請聯(lián)系管理員");
}
/**
* @param e
* @return
* @Description 請求參數(shù)異常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public RR handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
return RR.exception("請求參數(shù)錯誤:[" + e.getBindingResult().getFieldError().getDefaultMessage() + "]");
}
/**
* @param e
* @return
* @Description 系統(tǒng)業(yè)務(wù)服務(wù)異常
*/
@ExceptionHandler(ServerException.class)
public RR handleServerException(ServerException e) {
return RR.exception(e.getMessage());
}
/**
* @param e
* @return
* @Description 令牌校驗異常
*/
@ExceptionHandler(ExpireException.class)
public RR handleExpireException(ExpireException e) {
return RR.expire(e.getMessage());
}
/**
* @param e
* @return
* @Description 無權(quán)訪問異常
*/
@ExceptionHandler(AccessDeniedException.class)
public RR handleAccessDeniedException(AccessDeniedException e) {
return RR.forbidden(e.getMessage());
}
/**
* @param e
* @return
* @Description 自定義重復(fù)操作異常
*/
public RR handleRepeatHandleException(RepeatHandleException e) {
return RR.exception("您的請求已發(fā)送,請勿重復(fù)操作!");
}
/**
* @param e
* @return
* @Description 登錄異常處理
*/
@ExceptionHandler(AuthenticationException.class)
public RR handleAuthenticationException(AuthenticationException e) {
return RR.exception(e.getMessage());
}
}
然后我們用Swagger來測試一下接口
1.用戶名為空

2.手機號格式錯誤

通過返回結(jié)果可以看到,我們的校驗注解已經(jīng)幫我們按照指定的校驗方式校驗了指定的字段屬性,我們在統(tǒng)一的全局異常處理類中將提示信息封裝成需要的返回結(jié)果就可以了。
分組校驗
有的童鞋在此可能有疑問了,上述方法雖然可行,但我在新增用戶和修改用戶兩個接口中,新增用戶的用戶id是自動生成的,無需校驗;修改用戶的用戶id是必傳的,則需校驗。在此業(yè)務(wù)場景中,那豈不是需要聲明兩個實體類,但這兩個實體類中的屬性又大致相同,這不是增加麻煩嗎?其實不然,在此我們可以用到 groups 屬性來解決此場景下的問題。
聲明分組
注意:在聲明分組的時候盡量加上 extend javax.validation.groups.Default 否則,在你聲明@Validated(Update.class)的時候,就會出現(xiàn)你在默認沒添加groups = {}的時候的校驗組@Email(message = "郵箱格式不對"),會不去校驗,因為默認的校驗組是groups = {Default.class}。
/**
* 數(shù)據(jù)新增分組
*/
public interface Create extends Default {
}
/**
* 數(shù)據(jù)更新分組
*/
public interface Update extends Default {
}
校驗注解中添加分組,groups 為一個數(shù)組,可以添加多個分組
@NotNull(message = "id不能為空" , groups = Update.class)
private Long id;
@NotBlank(message = "用戶名不能為空" , groups = {Create.class, Update.class})
@Length(max = 10, message = "用戶名最長為10位")
private String name;
修改Controller中的@Validated注解,聲明校驗分組
@PermissionCheck("account:manager:add")
@PostMapping(value = "/add", produces = BaseConsts.REQUEST_HEADERS_CONTENT_TYPE)
@ApiOperation(value = "用戶管理-添加用戶接口", notes = "用戶管理-添加用戶接口", httpMethod = BaseConsts.REQUEST_METHOD, response = RR.class)
public RR add(@Validated(Create.class) @RequestBody Account account) throws Exception {
return RR.success("添加用戶成功");
}
@PermissionCheck("account:manager:edit")
@PostMapping(value = "/edit", produces = BaseConsts.REQUEST_HEADERS_CONTENT_TYPE)
@ApiOperation(value = "用戶管理-修改用戶接口", notes = "用戶管理-修改用戶接口", httpMethod = BaseConsts.REQUEST_METHOD, response = RR.class)
public RR edit(@Validated(Update.class) @RequestBody Account account) throws Exception {
return RR.success("編輯用戶成功");
}
使用相同的請求參數(shù)測試一下添加用戶和修改用戶的接口
測試添加接口

測試修改接口

通過接口的返回結(jié)果可以看到,新增用戶的接口并沒有校驗id這個參數(shù)了,而修改用戶的接口中則校驗了id不能為空。
常用校驗注解
以上就是樓主在項目中使用validation的總結(jié)歸納,下面收集了一些常用注解,紅色的標注則是樓主在項目中用的比較多的。
JSR提供的校驗注解:
@Null 被注釋的元素必須為 null
@NotNull 被注釋的元素必須不為 null
@AssertTrue 被注釋的元素必須為 true
@AssertFalse 被注釋的元素必須為 false
@Min(value) 被注釋的元素必須是一個數(shù)字,其值必須大于等于指定的最小值
@Max(value) 被注釋的元素必須是一個數(shù)字,其值必須小于等于指定的最大值
@DecimalMin(value) 被注釋的元素必須是一個數(shù)字,其值必須大于等于指定的最小值
@DecimalMax(value) 被注釋的元素必須是一個數(shù)字,其值必須小于等于指定的最大值
@Size(max=, min=) 被注釋的元素的大小必須在指定的范圍內(nèi)
@Digits (integer, fraction) 被注釋的元素必須是一個數(shù)字,其值必須在可接受的范圍內(nèi)
@Past 被注釋的元素必須是一個過去的日期
@Future 被注釋的元素必須是一個將來的日期
@Pattern(regex) 被注釋的元素必須符合指定的正則表達式
Hibernate Validator提供的校驗注解:
@NotBlank() 驗證字符串非null且非空格,長度必須大于0
@Email 被注釋的元素必須是電子郵箱地址
@Length(min=,max=) 被注釋的字符串的大小必須在指定的范圍內(nèi)
@NotEmpty 被注釋的字符串的必須非空
@Range(min=,max=,message=) 被注釋的元素必須在合適的范圍內(nèi)
參考博文: http://www.dhdzp.com/article/157604.htm
到此這篇關(guān)于Spring-Validation 后端數(shù)據(jù)校驗的實現(xiàn)的文章就介紹到這了,更多相關(guān)Spring Validation數(shù)據(jù)校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java接口回調(diào)和方法回調(diào)的簡單實現(xiàn)步驟
這篇文章主要介紹了Java接口回調(diào)和方法回調(diào)的相關(guān)資料,接口回調(diào)是一種設(shè)計模式,實現(xiàn)三方解耦,調(diào)用者提供接口實現(xiàn),文中通過代碼介紹的非常詳細,需要的朋友可以參考下2025-03-03
解決Spring Boot 多模塊注入訪問不到j(luò)ar包中的Bean問題
這篇文章主要介紹了解決Spring Boot 多模塊注入訪問不到j(luò)ar包中的Bean問題。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
詳解Spring AOP 實現(xiàn)“切面式”valid校驗
本篇文章主要介紹了詳解Spring AOP 實現(xiàn)“切面式”valid校驗,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
nacos注冊中心單節(jié)點ap架構(gòu)源碼解析(最新推薦)
這篇文章主要介紹了nacos注冊中心單節(jié)點ap架構(gòu)源碼解析,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01
SpringBoot結(jié)合JWT登錄權(quán)限控制的實現(xiàn)
本文主要介紹了SpringBoot結(jié)合JWT登錄權(quán)限控制的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07

