spring使用validation參數(shù)及全局異常檢測方式
1.validation參數(shù)驗證工具
1.1.validation-api技術(shù)鏈
validation-api是一個Java的數(shù)據(jù)校驗規(guī)范,它定義了一套用于校驗Java Bean的API。它是JSR 303規(guī)范的一部分,也被稱為Bean Validation。validation-api提供了一系列的注解,用于在Java類的字段、方法參數(shù)和方法返回值上添加校驗規(guī)則。這些注解包括@NotNull、@Size、@Min、@Max等等,每個注解都有特定的校驗規(guī)則,用于驗證數(shù)據(jù)是否滿足特定的條件。
Hibernate Validator是validation-api的唯一實現(xiàn)。除了提供注解和校驗規(guī)則,Hibernate Validator還提供了一系列的工具類和接口,用于處理校驗結(jié)果和錯誤信息。它可以將校驗結(jié)果封裝為一個Validator對象,并提供了各種方法來獲取校驗結(jié)果、錯誤信息和錯誤類型。Hibernate Validator還支持國際化,可以根據(jù)不同的語言環(huán)境顯示相應(yīng)的錯誤信息。它還提供了可自定義的錯誤消息模板,可以根據(jù)實際需求來設(shè)置錯誤消息的格式和內(nèi)容。
spring-boot-starter-validation是一個Spring Boot的starter,用于集成和簡化Spring框架中的數(shù)據(jù)校驗功能。spring-boot-starter-validation通過自動配置的方式,將Hibernate Validator集成到了Spring Boot的應(yīng)用中,從而簡化了數(shù)據(jù)校驗的配置過程。通過引入這個starter,我們可以在應(yīng)用中使用標(biāo)準(zhǔn)的注解來進(jìn)行數(shù)據(jù)校驗,而不需要手動配置和引入相關(guān)的依賴項。
1.2.validation常用注解
validation-api提供了一些常用的注解
@NotNull | 用于校驗字段或方法參數(shù)的值不能為空 |
@NotEmpty | 用于校驗字符串、集合或數(shù)組的值不能為空,且長度不能為0 |
@NotBlank | 用于校驗字符串的值不能為空或只包含空格 |
@Size | 用于校驗字符串、集合或數(shù)組的長度是否在指定范圍內(nèi) |
@Min | 用于校驗數(shù)字的值是否大于等于指定的最小值 |
@Pattern | 用于校驗字符串的值是否匹配指定的正則表達(dá)式 |
用于校驗字符串的值是否符合Email格式 | |
@DecimalMin | 用于校驗數(shù)字的值是否大于等于指定的最小值,可以指定最小值的精度 |
Hibernate Validator 提供了一些拓展注解,用于在 validation-api 注解基礎(chǔ)上實現(xiàn)更復(fù)雜的數(shù)據(jù)校驗。
以下是一些常見的 Hibernate Validator 拓展注解(部分)
@URL | 用于校驗字符串的值是否符合 URL 地址格式 |
@CreditCardNumber | 用于校驗信用卡號的格式是否正確 |
@Currency | 用于校驗貨幣代碼是否正確 |
@ISBN | 用于校驗國際標(biāo)準(zhǔn)書號(ISBN)是否正確 |
@Range | 用于校驗數(shù)字的值是否在指定范圍內(nèi) |
1.3.代碼示例
對于一個請求參數(shù),根據(jù)需求進(jìn)行注解申明
import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; import lombok.Data; @Data public class ReqCreateCatalog { @NotEmpty private String gameId; @DecimalMin(value = "1") @DecimalMax(value = "2") private int type; //目標(biāo)目錄 @Size(max = 50, message = "名稱長度不能超過{max}個字符") private String catalog; }
controller方法參數(shù)增加@Valid注解
@PostMapping(value = "/createCatalog") public Response create(@Valid @RequestBody ReqCreateCatalog req) { }
如果請求故意把gameId參數(shù)設(shè)為空,
則程序輸出異常日志
2. 全局異常處理器
2.1.使用@RestControllerAdvice攔截異常
上面的例子可以看出,當(dāng)驗證器拋出MethodArgumentNotValidException異常,如果沒有一個全局異常捕獲器對其進(jìn)行捕獲并進(jìn)行轉(zhuǎn)義,前端得到的響應(yīng)很奇怪。
SpringMVC使用@RestControllerAdvice注解對全局異常進(jìn)行攔截,例如下面的代碼
(也可以使用@ControllerAdvice注解,但每個方法還需要添加@ResponseBody注解)
@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public Response<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("請求地址'{}',參數(shù)校驗失敗'{}'", requestURI, e.getMessage()); return Response.fail(I18nConstants.COMMON_ILLEGAL_PARAMS); } @ExceptionHandler(BusinessRequestException.class) public Response<Object> handleBusinessRequestException(BusinessRequestException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("請求地址'{}',權(quán)限碼校驗失敗'{}'", requestURI, e.getMessage()); return Response.fail(e.getErrorCode()); } @ExceptionHandler(value = Exception.class) public Response<Object> handleException(Exception e, HttpServletRequest request) { LoggerUtil.error("", e); return Response.fail(I18nConstants.COMMON_INTERNAL_ERROR); } }
2.2.異常攔截方法有以下幾個注意地方
- 方法名必須以handle開頭;
- 需要添加@ExceptionHandler注解,注解的值是一個異常類數(shù)組,當(dāng)value為空,則默認(rèn)取方法的異常參數(shù)類型;
- 當(dāng)程序觸發(fā)了一個異常,如果在全局異常攔截器找不到映射,則會遞歸找它的父異常,則到父類Throwalbe為止;
- 如果多個@RestControllerAdvice示例綁定了同一個異常,程序不會報錯,但只有一個攔截器起作用。
2.3.使用案例
使用全局異常攔截器,重新發(fā)起請求,可以看到客戶端輸出:
{ "success": false, "message": 1003, //I18nConstants.COMMON_ILLEGAL_PARAMS "data": null }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Mybatis數(shù)據(jù)批量插入如何實現(xiàn)
這篇文章主要介紹了Mybatis數(shù)據(jù)批量插入如何實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07Java結(jié)合redistemplate使用分布式鎖案例講解
在Java中使用RedisTemplate結(jié)合Redis來實現(xiàn)分布式鎖是一種常見的做法,特別適用于微服務(wù)架構(gòu)或多實例部署的應(yīng)用程序中,以確保數(shù)據(jù)的一致性和避免競態(tài)條件,下面給大家分享使用Spring Boot和RedisTemplate實現(xiàn)分布式鎖的案例,感興趣的朋友一起看看吧2024-08-08如何在Intellij中安裝LeetCode刷題插件方便Java刷題
這篇文章主要介紹了如何在Intellij中安裝LeetCode刷題插件方便Java刷題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08解決mybatis 執(zhí)行mapper的方法時報空指針問題
這篇文章主要介紹了解決mybatis 執(zhí)行mapper的方法時報空指針問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07