上文測試開發專題:如何在spring-boot中進行參數校驗,我們討論了如何使用@Min、@Max等注解進行參數校驗,主要是針對基本數據類型和級聯對象進行參數校驗的演示,但是在實際中我們往往需要更為復雜的校驗規則,比如注冊用戶的密碼和確認密碼進行校驗,這個時候基本的注解就無法滿足我們的要求了,需要去按照業務需求去自定義注解進行校驗
元注解
在自定義注解之前我們有必要了解一些元注解,元注解就是在注解上的注解,可以對一個注解進行配置,元注解包括@Retention、@Target、@Document、@Inherited四種
-
@Retention,表示注解保留到什么時候,有以下三種模式
- @Retention(RetentionPolicy.SOURCE) 表示注解僅存在於源碼中,在class字節碼文件中不包含
- @Retention(RetentionPolicy.CLASS) 表示 默認的保留策略,注解會在class字節碼文件中存在,但運行時無法獲得
- @Retention(RetentionPolicy.RUNTIME) 表示注解會在class字節碼文件中存在,在運行時可以通過反射獲取到
-
@Target表示注解的作用目標是什么,只列出下面幾個,剩余的大家自行谷歌把
- @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,能夠讓有用戶明白是哪里錯了,下篇文章我們將介紹這塊的內容,敬請關注!!
歡迎大家去 我的博客 瞅瞅,里面有更多關於測試實戰的內容哦!!