1. 程式人生 > >springboot學習(二十二)_ 使用@Constraint註解自定義驗證註解

springboot學習(二十二)_ 使用@Constraint註解自定義驗證註解

最近專案在使用如@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判斷肯定讓人看的頭痛。好了,玩的開心!