1.为什么要使用自定义校验器
//当前需求,该属性校验需要满足不为null,并且是0或者1的整数
@NotNull(message = "显示状态不能为空")
@Pattern(regexp = "^[0-1]$", message = "显示状态格式为0或者1")
private Integer isshow;
以上写法是否正确?答案是false,并且会报错
javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.Pattern' validating type 'java.lang.Integer'.
原因是数值类型会使正则表达式失效,所以需要使用自定义校验器
2.如何实现自定义校验器
①自定义校验注解
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {EnumConstraintValidator.class})//校验规则来自EnumConstraintValidator.class
public @interface EnumValidate {
String message() default "{com.morris.common.valid.EnumValidate.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
//存放校验规则
int[] values() default {};
}
//默认的错误验证信息存放在resources下的配置文件内,中文需要转unicode
ValidationMessages.properties
com.morris.common.valid.EnumValidate.message=\u663e\u793a\u72b6\u6001\u7684\u503c\u9700\u8981\u662f\u0030\u6216\u8005\u0031
②自定义校验规则类
public class EnumConstraintValidator implements ConstraintValidator<EnumValidate, Integer> {
//存放校验注解的values
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(EnumValidate constraintAnnotation) {
//获取校验注解的values,就是[0,1]
int[] values = constraintAnnotation.values();
//遍历校验注解的values,添加到set
for (int value : values) {
set.add(value);
}
}
//校验逻辑
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
//判断被校验值是不是0或者1
return set.contains(value);
}
}
③实现对属性 isshow 的校验
@NotNull(message = "显示状态不能为空")
@EnumValidate(values = {0, 1})
private Integer isshow;