SpringBoot使用validation-api實現(xiàn)參數(shù)校驗的示例
我們在開發(fā)Java項目的時候,經(jīng)常需要對參數(shù)進行一些必填項、格式、長度等進行校驗,如果手寫代碼對參數(shù)校驗,每個接口會需要很多低級的代碼,這樣會降低代碼的可讀性。那么我們能不能使用一種比較優(yōu)雅的方式來實現(xiàn),對請求中的參數(shù)進行校驗?zāi)兀?/p>
knife4j的安裝與使用可參考我的博客:SpringBoot使用knife4j進行在線接口調(diào)試
正文
ValidationApi框架就是用來解決參數(shù)校驗中代碼冗余問題,ValidationApi
框架提供一些注解用來幫助我們對請求參數(shù)進行校驗:
SpringBoot使用validation-api實現(xiàn)參數(shù)校驗
注入依賴
<!--參數(shù)校驗--> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <!--提供一些字符串操作--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.3.2</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version> <optional>true</optional> </dependency> <!--knife4j接口--> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>2.0.4</version> </dependency>
UserPojoReq.java請求封裝類
如果成員變量是其他對象實體,該變量必須加 @Valid
,否則嵌套中的驗證不生效
@Setter @Getter @ToString @ApiModel("用戶對象") public class UserPojoReq extends Request implements Serializable { private static final long serialVersionUID = -354657839724457905L; @ApiModelProperty(required = true, notes = "主鍵", example = "123") private String id; @ApiModelProperty(required = true, notes = "用戶名", example = "luo") @NotNull(message = "用戶姓名為必填項,不得為空") @Size(min = 2,max = 20,message = "用戶名長度要在2—8個字符") private String name; @ApiModelProperty(required = true, notes = "消息", example = "消息") private String msg; }
CouponTypeEnum.class :錯誤碼枚舉類
@Getter public enum CouponTypeEnum { PARAMETER_ERROR(1001, "請求參數(shù)有誤!"), UNKNOWN_ERROR(9999, "未知的錯誤!”); /** * 狀態(tài)值 */ private int couponType; /** * 狀態(tài)描述 */ private String couponTypeDesc; CouponTypeEnum(int couponType, String couponTypeDesc){ this.couponType = couponType; this.couponTypeDesc = couponTypeDesc; } public static String getDescByType(int couponType) { for (CouponTypeEnum type : CouponTypeEnum.values()) { if (type.couponType == couponType) { return type.couponTypeDesc; } } return null; } public String getcouponTypeStr(){ return String.valueOf(this.couponType); } }
BusinessException.java:自定義業(yè)務(wù)異常類
/** * 業(yè)務(wù)自定義異常 */ @Getter public class BusinessException extends RuntimeException { private static final long serialVersionUID = -1895174013651345407L; private final CouponTypeEnum errorCode; private String primaryErrorCode; private String primaryErrorMsg; private String primaryErrorIP; public BusinessException(CouponTypeEnum errorCode) { this(errorCode, errorCode.getCouponTypeDesc()); } public BusinessException(CouponTypeEnum errorCode, String message) { super(message); this.errorCode = errorCode; } public BusinessException(CouponTypeEnum errorCode, String message,String primaryErrorCode,String primaryErrorMsg,String primaryErrorIP) { super(message); this.errorCode = errorCode; this.primaryErrorCode=primaryErrorCode; this.primaryErrorMsg=primaryErrorMsg; this.primaryErrorIP=primaryErrorIP; } public BusinessException(CouponTypeEnum errorCode,String primaryErrorCode,String primaryErrorMsg,String primaryErrorIP) { this(errorCode, errorCode.getCouponTypeDesc()); this.primaryErrorCode=primaryErrorCode; this.primaryErrorMsg=primaryErrorMsg; this.primaryErrorIP=primaryErrorIP; } }
GlobalExceptionHandler.class 攔截異常并統(tǒng)一處理
MissingServletRequestParameterException
:必填項為null異常HttpMessageNotReadableException
:參數(shù)類型不匹配異常MethodArgumentNotValidException
:JSON校驗失敗異常(比如長度等)BusinessException
:自定義的異常Exception
:其他異常
@RestControllerAdvice("com.luo.producer.controller") @Slf4j public class GlobalExceptionHandler { /** * 忽略參數(shù)異常處理器 * * @param e 忽略參數(shù)異常 * @return Response */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MissingServletRequestParameterException.class) public Response parameterMissingExceptionHandler(MissingServletRequestParameterException e) { log.error("", e); return new Response(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "請求參數(shù) " + e.getParameterName() + " 不能為空"); } /** * 缺少請求體異常處理器 * * @param e 缺少請求體異常 * @return Response */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(HttpMessageNotReadableException.class) public Response parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) { log.error("", e); return new Response(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "參數(shù)體不能為空"); } /** * 參數(shù)效驗異常處理器 * * @param e 參數(shù)驗證異常 * @return ResponseInfo */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MethodArgumentNotValidException.class) public Response parameterExceptionHandler(MethodArgumentNotValidException e) { log.error("", e); // 獲取異常信息 BindingResult exceptions = e.getBindingResult(); // 判斷異常中是否有錯誤信息,如果存在就使用異常中的消息,否則使用默認(rèn)消息 if (exceptions.hasErrors()) { List<ObjectError> errors = exceptions.getAllErrors(); if (!errors.isEmpty()) { // 這里列出了全部錯誤參數(shù),按正常邏輯,只需要第一條錯誤即可 FieldError fieldError = (FieldError) errors.get(0); return new Response(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), fieldError.getDefaultMessage()); } } return new Response(CouponTypeEnum.PARAMETER_ERROR); } /** * 自定義參數(shù)錯誤異常處理器 * * @param e 自定義參數(shù) * @return ResponseInfo */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler({BusinessException.class}) public Response paramExceptionHandler(BusinessException e) { log.error("", e); // 判斷異常中是否有錯誤信息,如果存在就使用異常中的消息,否則使用默認(rèn)消息 if (!StringUtils.isEmpty(e.getMessage())) { return new Response(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), e.getMessage()); } return new Response(CouponTypeEnum.PARAMETER_ERROR); } /** * 其他異常 * * @param e * @return */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler({Exception.class}) public Response otherExceptionHandler(Exception e) { log.error("其他異常", e); // 判斷異常中是否有錯誤信息,如果存在就使用異常中的消息,否則使用默認(rèn)消息 if (!StringUtils.isEmpty(e.getMessage())) { return new Response(CouponTypeEnum.UNKNOWN_ERROR.getcouponTypeStr(), e.getMessage()); } return new Response(CouponTypeEnum.UNKNOWN_ERROR); } }
驗證
測試接口
@Valid
被標(biāo)記的實體將會開啟一個校驗的功能
@RequestBody
:請求實體需要加上@RequestBody
否則MethodArgumentNotValidException
異常將會被識別成Exception
異常,提示信息將與預(yù)期不符。
@RestController @Slf4j public class UserController { @PostMapping("/helloluo") @MyPermissionTag(value = "true") public String helloluo(@RequestBody @Valid UserPojoReq userPojoReq){ return "Hello World”+userPojoReq; } }
模擬請求參數(shù),進行接口訪問:
到此這篇關(guān)于SpringBoot使用validation-api實現(xiàn)參數(shù)校驗的示例的文章就介紹到這了,更多相關(guān)SpringBoot validation參數(shù)校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring?Boot集成validation實現(xiàn)參數(shù)校驗功能
- SpringBoot使用Validation包進行輸入?yún)?shù)校驗
- SpringBoot使用Validation進行參數(shù)校驗的示例詳解
- SpringBoot集成Validation參數(shù)校驗
- SpringBoot使用validation做參數(shù)校驗的實現(xiàn)步驟
- SpringBoot使用validation-api實現(xiàn)對枚舉類參數(shù)校驗的方法
- spring boot validation參數(shù)校驗實例分析
- springboot+dubbo+validation 進行rpc參數(shù)校驗的實現(xiàn)方法
- spring?參數(shù)校驗Validation示例詳解
相關(guān)文章
使用RestTemplate訪問https實現(xiàn)SSL請求操作
這篇文章主要介紹了使用RestTemplate訪問https實現(xiàn)SSL請求操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Spring?Boot項目集成Knife4j接口文檔的實例代碼
Knife4j就相當(dāng)于是swagger的升級版,對于我來說,它比swagger要好用得多<BR>,這篇文章主要介紹了Spring?Boot項目集成Knife4j接口文檔的示例代碼,需要的朋友可以參考下2021-12-12java 中序列化與readResolve()方法的實例詳解
這篇文章主要介紹了java 中序列化與readResolve()方法的實例詳解的相關(guān)資料,這里提供實例幫助大家理解這部分知識,需要的朋友可以參考下2017-08-08SpringMVC+Mybatis實現(xiàn)的Mysql分頁數(shù)據(jù)查詢的示例
本篇文章主要介紹了SpringMVC+Mybatis實現(xiàn)的Mysql分頁數(shù)據(jù)查詢的示例,具有一定的參考價值,有興趣的可以了解一下2017-08-08Springboot詳解整合SpringSecurity實現(xiàn)全過程
Spring Security基于Spring開發(fā),項目中如果使用Springboot作為基礎(chǔ),配合Spring Security做權(quán)限更加方便,而Shiro需要和Spring進行整合開發(fā)。因此作為spring全家桶中的Spring Security在java領(lǐng)域很常用2022-07-07