「Java程式設計師」還在用if判斷引數是否規範?JSR303,你學會了嗎?
在日常開發中,對前端傳過來的引數,我們都會進行非空等一些校驗,稍微複雜一些的還有對郵箱的校驗、網址的校驗等等,今天,教你使用JSR303註解輕鬆實現引數校驗~
JSR303是什麼?
JSR 是Java Specification Requests的縮寫,意為Java 規範提案。是指向JCP(Java Community Process)提出新增一個標準化技術規範的正式請求。任何人都可以提交JSR,以向Java平臺增添新的API和服務。JSR已成為Java界的一個重要標準。那JSR303就指的就是303號提案。
我們主要分四個方面來學習它:
單一方法種使用
統一異常處理
分組校驗
自定義校驗註解
一、在單一方法中使用
第一步,在Bean中新增校驗註解,在message中新增自定義錯誤資訊。如:
其中,message屬性指定錯誤時的提示資訊。
第二步,
在方法中需要校驗的引數前加@Valid註解啟用校驗:
至此,簡單的引數校驗就已經啟用了。當未指定校驗註解的message屬性時,預設使用org\hibernate\validator\ValidationMessages。properties。
那麼當校驗失敗時,我們如何在方法中獲取這些message呢?
很簡單,我們只需要在校驗引數後,緊跟一個BindingResult物件即可,關於物件中的方法,請閱讀統一異常處理一節。
二、統一異常處理
第一步,我們新建自定義異常類,並新增如下註解:
@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
本示例中,為提高程式碼靈活性,
使用列舉類統一定義異常資訊及狀態碼。
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介面(不同的介面代表不同的組),如下:
第二步,在校驗註解中,新增group屬性:
第三步,在方法上使用@Validated註解,並指定分組,多個分組可用“,”隔開
因為在本專案中,使用了統一異常處理,所以註釋掉了此處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
第三步,
在resources下新建ValidationMessages。properties檔案,新增屬性
com。atguigu。guli。listvalue。message=顯示狀態只能為0或1
第四步,測試如下:
你學會了嗎?收藏點贊加關注,技術學習不迷路~