springboot 自定义校验注解

当框架提供的注解不知足于实际开发需求时,须要对其进行扩展。java

@Target :指定注解能够用于:字段、注解、参数。正则表达式

  • ElementType选项说明:
CONSTRUCTOR:用于描述构造器
FIELD:用于描述域
LOCAL_VARIABLE:用于描述局部变量
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述参数
TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention :指定生命周期。框架

  • RetentionPolicy 说明:
SOURCE:在源文件中有效(源文件保留)
CLASS:在class文件中有效(class保留)
RUNTIME:在运行时有效(运行时保留)

@Documented: 使得该注解 javadoc工具记录ide

@Constraint :指定验证器,实现类。~~~~工具

groups()payload()是自定义效验注解必须的内容。code

List接口是可选的,同一个效验注解在一个字段使用屡次,须要使用@List接口

简单举例:生命周期

  • 校验注解
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = SizeValidator.class)
public @interface SizeValid {
    //错误提示信息,必须存在
    String message() default "";
    
    long max();
    
    long min() default 0;

    //分组,必须存在
    Class<?>[] groups() default {};

    //负载,必须存在
    Class<? extends Payload>[] payload() default {};

    //多个分组时使用
    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface List {
        SizeValid[] value();
    }
}
  • 实现类

ConstraintValidator<A, T>接口: A是自定义效验注解,T是支持效验的数据类型。
initialize():初始化验证器相关内容。
isValid():实际验证方法。开发

@Slf4j
public class SizeValidator implements ConstraintValidator<SizeValid, String> {

    private long min;
    private long max;
    /**匹配双字节字符正则表达式*/
    private static final String REGEX = "[^\\x00-\\xff]";

    /**
     * 获取注解属性的值
     *
     * @param constraintAnnotation
     */
    @Override
    public void initialize(NameValid constraintAnnotation) {
        min = constraintAnnotation.min();
        max = constraintAnnotation.max();
    }

    /**
     * @param value
     * @param context
     * @return 是否经过验证
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(value == null) return true;
        long length = value.replaceAll(REGEX, "aa").length();
        return min <= length && max >= length;
    }
}