「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

在日常開發中,對前端傳過來的引數,我們都會進行非空等一些校驗,稍微複雜一些的還有對郵箱的校驗、網址的校驗等等,今天,教你使用JSR303註解輕鬆實現引數校驗~

JSR303是什麼?

JSR 是Java Specification Requests的縮寫,意為Java 規範提案。是指向JCP(Java Community Process)提出新增一個標準化技術規範的正式請求。任何人都可以提交JSR,以向Java平臺增添新的API和服務。JSR已成為Java界的一個重要標準。那JSR303就指的就是303號提案。

我們主要分四個方面來學習它:

單一方法種使用

統一異常處理

分組校驗

自定義校驗註解

一、在單一方法中使用

第一步,在Bean中新增校驗註解,在message中新增自定義錯誤資訊。如:

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

其中,message屬性指定錯誤時的提示資訊。

第二步,

在方法中需要校驗的引數前加@Valid註解啟用校驗:

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

至此,簡單的引數校驗就已經啟用了。當未指定校驗註解的message屬性時,預設使用org\hibernate\validator\ValidationMessages。properties。

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

那麼當校驗失敗時,我們如何在方法中獲取這些message呢?

很簡單,我們只需要在校驗引數後,緊跟一個BindingResult物件即可,關於物件中的方法,請閱讀統一異常處理一節。

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

二、統一異常處理

第一步,我們新建自定義異常類,並新增如下註解:

@RestControllerAdvice(basePackages = “com。atguigu。guli。product。controller”)

該註解等價於:

@ControllerAdvice(basePackages = “com。atguigu。guli。product。controller”)@ResponseBody

第二步,

編寫異常方法,處理異常。@ExceptionHandler(value = Throwable。class)註解標明瞭該方法處理的異常型別:

//引入log@Slf4j@RestControllerAdvice(basePackages = “com。atguigu。guli。product。controller”)public class GuliException { //處理資料驗證異常 @ExceptionHandler(value = MethodArgumentNotValidException。class) public R dealValidException(MethodArgumentNotValidException e){ BindingResult result = e。getBindingResult(); Map map = new HashMap<>(); result。getFieldErrors()。forEach(item -> { String field = item。getField(); String defaultMessage = item。getDefaultMessage(); map。put(field,defaultMessage); }); log。error(“異常資訊:{},異常型別:{}”,e。getMessage(),e。getClass()); return R。error(BizCode。VALID_EXCEPTION。getCode(),BizCode。VALID_EXCEPTION。getMessage())。put(“data”,map); } //處理所有異常 @ExceptionHandler(value = Throwable。class) public R dealValidException(Throwable e){ log。error(“異常資訊:{},異常型別:{}”,e。getMessage(),e。getClass()); return R。error(); }}

本示例中,為提高程式碼靈活性,

使用列舉類統一定義異常資訊及狀態碼。

public enum BizCode { UNKNOWN_EXCEPTION(10000,“系統未知異常”), VALID_EXCEPTION(10001,“資料校驗異常”); private int code; private String message; BizCode(int code,String message){ this。code = code; this。message = message; } public int getCode() { return code; } public String getMessage() { return message; }}

常用註解:(此處簡寫,具體含義開發中可以點進註解檢視。唐突了唐突了。。。)

@NotBlank 非null,並且必須包含非空字元

@Pattern 自定義校驗規則

@Min 最小值

@Url Url地址校驗

三、 分組校驗

第一步,

新建AddValid和UpdateValid介面(不同的介面代表不同的組),如下:

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

第二步,在校驗註解中,新增group屬性:

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

第三步,在方法上使用@Validated註解,並指定分組,多個分組可用“,”隔開

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

因為在本專案中,使用了統一異常處理,所以註釋掉了此處BindingResult相關程式碼。

注意,在有分組校驗的情況下@Validated(value = {AddValid.class})),預設未填寫group屬性的校驗註解不生效。

四、自定義校驗註解

第一步,

新建註解@ListValue如下:

import javax。validation。Constraint;import javax。validation。Payload;import java。lang。annotation。Documented;import java。lang。annotation。Retention;import java。lang。annotation。Target;import static java。lang。annotation。ElementType。*;import static java。lang。annotation。ElementType。TYPE_USE;import static java。lang。annotation。RetentionPolicy。RUNTIME;@Documented@Constraint(validatedBy = {ListValueValidator。class})//指定處理校驗的類@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)public @interface ListValue { String message() default “{com。atguigu。guli。listvalue。message}”;//JSR303規定必須有的三個屬性,指定錯誤資訊從哪獲取 Class<?>[] groups() default { };//JSR303規定必須有的三個屬性,指定分組 Class<? extends Payload>[] payload() default { };//JSR303規定必須有的三個屬性,指定負載 int[] vals() default {};//自定義屬性:int陣列}

第二步,

新建ListValueValidator校驗處理類(實現ConstraintValidator介面)如下:

import javax。validation。ConstraintValidator;import javax。validation。ConstraintValidatorContext;import java。util。HashSet;import java。util。Set;//自定義校驗處理//ConstraintValidator是一個泛型介面,第一個引數表明註解型別,第二個引數表明註解作用在哪個型別上public class ListValueValidator implements ConstraintValidator { Set set = new HashSet<>(); //校驗 @Override public boolean isValid(Integer value, ConstraintValidatorContext context) { return set。contains(value); } //初始化 @Override public void initialize(ListValue constraintAnnotation) { int[] vals = constraintAnnotation。vals(); for (int val : vals) { set。add(val); } }}

第三步,

在resources下新建ValidationMessages。properties檔案,新增屬性

com。atguigu。guli。listvalue。message=顯示狀態只能為0或1

第四步,測試如下:

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?

你學會了嗎?收藏點贊加關注,技術學習不迷路~