自定义注解校验时间

自定义注解的几个要素是:

(1)@Retention:注解的保留策略,

自定义注解校验时间

(2)@Target:注解的作用目标,是作用在接口、类、方法还是注解等地方 

自定义注解校验时间

(3)@Document:注解包含在javadoc中

(4)@Inherited:注解可以被继承

(5)注解解析器:解析自定义注解

 

 

实践一下,实现对Date的校验。

第一步:注解的定义:

@Documented
// 指定该注解可以使用的地方
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
// 指定实际进行校验的校验器,该校验器是自己写的且必须实现ConstraintValidator接口
@Constraint(validatedBy = MyDateAnnValidator.class)
public @interface MyDateValid {

    /**
     * 时间不早于
     * @return
     */
    String minDate() default "";

    /**
     * 时间不晚于
     * @return
     */
    String maxDate() default "";

    /**
     * 时间格式定义
     * @return
     */
    String pattern() default "yyyy-MM-dd";

    /**
     * 没加default给定默认值,使用注解的时候该属性必须赋值,否则报错
     * @return
     */
    String message();

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

第二步:实现:

public class MyDateAnnValidator implements ConstraintValidator<MyDateValid, Date> {

    private MyDateValid myDateValid;
    /**
     * Initializes the validator in preparation for
     * {@link #isValid(Object, ConstraintValidatorContext)} calls.
     * The constraint annotation for a given constraint declaration
     * is passed.
     * <p/>
     * This method is guaranteed to be called before any use of this instance for
     * validation.
     *
     * @param constraintAnnotation annotation instance for a given constraint declaration
     */
    @Override
    public void initialize(MyDateValid constraintAnnotation) {
        this.myDateValid = constraintAnnotation;
    }

    /**
     * Implements the validation logic.
     * The state of {@code value} must not be altered.
     * <p/>
     * This method can be accessed concurrently, thread-safety must be ensured
     * by the implementation.
     *
     * @param value   object to validate
     * @param context context in which the constraint is evaluated
     * @return {@code false} if {@code value} does not pass the constraint
     */
    @Override
    public boolean isValid(Date value, ConstraintValidatorContext context) {
        String pattern = myDateValid.pattern();
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        String myMinDate = myDateValid.minDate();
        String myMaxDate = myDateValid.maxDate();
        // 为空可以放过
        if (value == null){
            return true;
        }
        try {
            Date maxDate = null;
            Date minDate = null;
            if ("".equals(myMinDate)){
                // 未设置最小时间
                maxDate = df.parse(myDateValid.maxDate());
                // compareTo方法, 1:后者大于前者;-1:后者小于前者;0:两个相同
                return value.compareTo(maxDate) != 1;
            } else if ("".equals(myMaxDate)){
                // 未设置最大时间
                minDate = df.parse(myDateValid.minDate());
                return value.compareTo(minDate) >= 0;
            } else {
                // 设置了最大时间和最小时间
                maxDate = df.parse(myDateValid.maxDate());
                minDate = df.parse(myDateValid.minDate());
                return value.compareTo(maxDate) != 1 && value.compareTo(minDate) >= 0;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return false;
    }
}

用法:

    @MyDateValid(maxDate = "2099-01-01",message = "有效期限不能超过2099-01-01")
    private Date driverLicenseDate;
    
    @MyDateValid(minDate = "2019-01-01",message = "有效期限不能早于2019-01-01")
    private Date driverLicenseDate;

    @MyDateValid(minDate = "2019-01-01",maxDate = "2099-01-01",message = "有效期限不能早于2019-01-01,不能超过2099-01-01")
    private Date driverLicenseDate;

备注:如果想要改造一下message,也是可以的,注解中message设个default,然后在实现中你自己去自定义msg,用到的方法:

ctx.disableDefaultConstraintViolation();
ctx.buildConstraintViolationWithTemplate(msg).addConstraintViolation();

参考博客:https://blog.csdn.net/qq_34520606/article/details/78660014