更加靈活的參數校驗,Spring-boot自定義參數校驗註解
- 2020 年 5 月 15 日
- 筆記
- JAVA, spring-boot
上文測試開發專題:如何在spring-boot中進行參數校驗,我們討論了如何使用@Min、@Max等註解進行參數校驗,主要是針對基本數據類型和級聯對象進行參數校驗的演示,但是在實際中我們往往需要更為複雜的校驗規則,比如註冊用戶的密碼和確認密碼進行校驗,這個時候基本的註解就無法滿足我們的要求了,需要去按照業務需求去自定義註解進行校驗
元註解
在自定義註解之前我們有必要了解一些元註解,元註解就是在註解上的註解,可以對一個註解進行配置,元註解包括@Retention、@Target、@Document、@Inherited四種
-
@Retention,表示註解保留到什麼時候,有以下三種模式
- @Retention(RetentionPolicy.SOURCE) 表示註解僅存在於源碼中,在class位元組碼文件中不包含
- @Retention(RetentionPolicy.CLASS) 表示 默認的保留策略,註解會在class位元組碼文件中存在,但運行時無法獲得
- @Retention(RetentionPolicy.RUNTIME) 表示註解會在class位元組碼文件中存在,在運行時可以通過反射獲取到
-
@Target表示註解的作用目標是什麼,只列出下面幾個,剩餘的大家自行Google把
- @Target(ElementType.TYPE) 表示註解可以應用於介面、類、枚舉、註解
- @Target(ElementType.FIELD) 表示可以應用於欄位、成員變數、枚舉的常量等
- @Target(ElementType.METHOD)表示可以作用於方法
-
@Document表示註解包含在javadoc中
-
@Inherited表示註解可以被繼承
自定義校驗註解
就以用戶註冊為例,我們需要校驗密碼和確認密碼是否一致以及是否符合密碼的規則,先新建一個PasswordEqual註解類
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Constraint(validatedBy = PasswordValidator.class)
public @interface PasswordEqual {
String message() default "密碼不一樣";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
下面我們來解釋一下上面的註解,在PasswordEqual註解上,又標記了四個註解,前三個我們上面已經說過了。
這裡說一下@Constraint註解,它表示這個註解是一個驗證註解,並且通過validatedBy指定自定義校驗註解的關聯類,PasswordValidator類就是我們自定義的註解關聯的類。
註解裡面的groups和payload方法是模板方法,實現自定義註解必須寫這麼兩個方法。
定義驗證類
驗證類裡面包含具體的驗證邏輯了,下面是一個簡版的:
public class PasswordValidator implements ConstraintValidator<PasswordEqual, BannerCreateDto> {
@Override
public boolean isValid(BannerCreateDto dto, ConstraintValidatorContext constraintValidatorContext) {
return false;
}
}
這裡需要對上面的程式碼進行一下說明,實現自定義校驗類必須實現
ConstraintValidator介面,它是一個泛型介面,需要指定兩個類型參數,第一個是自定義註解類型,第二個類型指定自定義註解修飾目標的類型,就是準備把自定義註解標記到什麼類型上面。
必須重寫isValid方法,所有的校驗邏輯都在這個方法裡面,下面我們簡單寫一下:
@Override
public boolean isValid(UserDto dto, ConstraintValidatorContext constraintValidatorContext) {
if (dto.getPassword().equals(dto.getConfirmPassword())){
return true;
}
return false;
}
然後我們將自定義的註解類標記到UserDto類上:
@Builder
@Getter
@Setter
@PasswordEqual
public class UserDto {
@Length(min = 4, max = 10, message = "用戶名長度必須在4-10個字元之間")
private String name;
private String password;
private String confirmPassword;
}
接下來我們在寫一個簡單的創建用戶的介面:
@RestController
public class UserController {
@PostMapping("/v2/user/create")
@ResponseBody
public UserDto createUser(@RequestBody @Validated UserDto dto){
return dto;
}
}
注意這裡有要使用@ResponseBody能夠返回自動序列化自定義對象,並且要寫上 @Validated開啟校驗機制。
我們先輸入正確的密碼和確認密碼一下:
可以看到能夠正常的返回數據,這時再把兩個密碼改的不一樣,試試:
這個時候就拋出了異常,這裡的異常資訊是因為進了全局異常處理器,不清楚的童鞋可以看下之前的文章。我們再來看一下控制台的輸出:
控制台已經輸出了校驗的錯誤資訊。
總結
我們今天介紹了自定義參數校驗,並編寫了校驗註解和校驗類,但是最後返回給用戶的資訊非常不友好,需要針對參數校驗錯誤,能夠返回定義的message,能夠讓有用戶明白是哪裡錯了,下篇文章我們將介紹這塊的內容,敬請關注!!
歡迎大家去 我的部落格 瞅瞅,裡面有更多關於測試實戰的內容哦!!