自定义校验

自定义校验一般用于只需要文字表达信息的输出,校验逻辑业务化,涉及多个字段联合的可以结合使用前文说的联合校验(单个字段也可,校验逻辑写联合校验类中即可)

业务需求总是比框架提供的这些简单校验要复杂的多,我们可以自定义校验来满足我们的需求。自定义spring validation非常简单,主要分为两步。

1 自定义校验注解 
我们尝试添加一个“字符串不能包含空格”的限制。

复制代码

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {CannotHaveBlankValidator.class})<1>
public @interface CannotHaveBlank {
 
    //默认错误消息
    String message() default "不能包含空格";
 
    //分组
    Class<?>[] groups() default {};
 
    //负载
    Class<? extends Payload>[] payload() default {};
 
    //指定多个时使用
    @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        CannotHaveBlank[] value();
    }
 
}

复制代码

我们不需要关注太多东西,使用spring validation的原则便是便捷我们的开发,例如payload,List ,groups,都可以忽略。

  1.  自定义注解中指定了这个注解真正的验证者类。
  2.  编写真正的校验者类

复制代码

public class CannotHaveBlankValidator implements <1> ConstraintValidator<CannotHaveBlank, String> {
 
    @Override
    public void initialize(CannotHaveBlank constraintAnnotation) {

    }
 
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context <2>) {
        //null时不进行校验
        if (value != null && value.contains(" ")) {
            //获取默认提示信息
            String defaultConstraintMessageTemplate = context.getDefaultConstraintMessageTemplate();
            System.out.println("default message :" + defaultConstraintMessageTemplate);
            //禁用默认提示信息
            context.disableDefaultConstraintViolation();
            //设置提示语
            context.buildConstraintViolationWithTemplate("can not contains blank").addConstraintViolation();
            return false;
        }
        return true;
    }
}

复制代码

所有的验证者都需要实现ConstraintValidator接口,它的接口也很形象,包含一个初始化事件方法,和一个判断是否合法的方法。

public interface ConstraintValidator<A extends Annotation, T> {
 
    void initialize(A constraintAnnotation);
 
    boolean isValid(T value, ConstraintValidatorContext context);
}

intValidatorContext 这个上下文包含了认证中所有的信息,我们可以利用这个上下文实现获取默认错误提示信息,禁用错误提示信息,改写错误提示信息等操作。
一些典型校验操作,或许可以对你产生启示作用。

值得注意的一点是,自定义注解可以用在METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER之上,ConstraintValidator的第二个泛型参数T,是需要被校验的类型。