最近項目在使用如@NotNull @Max 等配合@vaild 注解進行驗證傳過來的參數校驗,然后通過統一異常處理,直接返回給前端,不用在業務代碼中對這些參數進行校驗。但是官方提供的並不能全部滿足項目的需求,我經過查找發現了@Constraint這個注解。
Constraint 詳細信息
@Null 被注釋的元素必須為 null
@NotNull 被注釋的元素必須不為 null
@AssertTrue 被注釋的元素必須為 true
@AssertFalse 被注釋的元素必須為 false
@Min(value) 被注釋的元素必須是一個數字,其值必須大於等於指定的最小值
@Max(value) 被注釋的元素必須是一個數字,其值必須小於等於指定的最大值
@DecimalMin(value) 被注釋的元素必須是一個數字,其值必須大於等於指定的最小值
@DecimalMax(value) 被注釋的元素必須是一個數字,其值必須小於等於指定的最大值
@Size(max, min) 被注釋的元素的大小必須在指定的范圍內
@Digits (integer, fraction) 被注釋的元素必須是一個數字,其值必須在可接受的范圍內
@Past 被注釋的元素必須是一個過去的日期
@Future 被注釋的元素必須是一個將來的日期
@Pattern(value) 被注釋的元素必須符合指定的正則表達式
需求
現在有的列表查詢,根據查詢條件進行查詢,當然這些查詢條件可以為null,如果存在值,就必須進行驗證。這里就對長度就行驗證,不為nul的時候 輸入字符不能為空串,且長度必須大於等於1且小於等於10
代碼實現
1、定義自定義注解
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
//代表處理邏輯是MyConstraintValidator類
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {
String message() default "參數校驗不通過,請重新輸入";;
long min();
long max();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2.處理類,需要實現ConstraintValidator接口
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, Object> {
private long max = 1;
private long min = 1;
@Override
public void initialize(MyConstraint constraintAnnotation) {
max = constraintAnnotation.max();
min = constraintAnnotation.min();
System.out.println("my validator init");
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
if(o == null){
return true;
}
if(o.toString().trim().length()>=min && o.toString().trim().length()<=max){
return true;
}
return false;
}
}
3.進行驗證
3.1 定義一個實體類User
@Data
public class User {
@MyConstraint( min = 1, max =10 )
private String name;
private String address;
}
3.2 全局異常中進行處理,這里只是看下效果,返回String字符串
@RestControllerAdvice
@Slf4j
public class KevinExceptionHandler {
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
log.error(e.getMessage(), e);
if (e instanceof BindException) {
BindException ex = (BindException) e;
List<ObjectError> allErrors = ex.getAllErrors();
ObjectError error = allErrors.get(0);
String defaultMessage = error.getDefaultMessage();
return defaultMessage;
} else {
return "error";
}
}
}
3.3controller測試方法
@RestController
public class Hello {
@RequestMapping(value = "hello")
public User hello(@Valid User user){
return user;
}
}
3.4 通過swagger 進行驗證
-
不輸入值,為null時
-
輸入空格
-
輸入超過長度
-
輸入正常值
總結
使用注解驗證參數配合異常處理,很方便且減少了很多業務代碼,各種if判斷肯定讓人看的頭痛。好了,玩的開心!