自定义注解验证主要实现两个类
1. 注解类
2. 注解对应的校验器类
注解类代码示例:
package ****.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = StringDateValidator.class)
@Inherited
public @interface StringDate {
String message() default "日期验证错误";
String value() default "yyyy-MM-dd";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
校验器类代码示例:
package ***.validation;
import ***.utils.DateUtil;
import ***.StringUtil;
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Date;
import java.util.Locale;
public class StringDateValidator implements ConstraintValidator<StringDate, String> {
private String value;
@Override
public void initialize(StringDate constraintAnnotation) {
value = constraintAnnotation.value();
}
@Override
public boolean isValid(String o, ConstraintValidatorContext constraintValidatorContext) {
String fieldName = "";
// 获取注解的字段名称,用于快速定位排查
if (constraintValidatorContext instanceof ConstraintValidatorContextImpl) {
ConstraintValidatorContextImpl validatorContext = (ConstraintValidatorContextImpl) constraintValidatorContext;
if (validatorContext.getConstraintViolationCreationContexts() != null
&& validatorContext.getConstraintViolationCreationContexts().size() > 0
&& validatorContext.getConstraintViolationCreationContexts().get(0).getPath() != null) {
fieldName = validatorContext.getConstraintViolationCreationContexts().get(0).getPath().asString();
}
}
if (StringUtil.isEmpty(o)) {// 当值为空字符时,认为值有效
return true;
}
String pattern = value.replaceAll("y|M|d|H|h|m|s|S", "[0-9]");
boolean matches = o.matches(pattern);
if (!matches) {
// 禁用默认错误信息,防止错误信息与自定义信息乱串
constraintValidatorContext.disableDefaultConstraintViolation();
String message = String.format(Locale.CHINESE, "[%s]日期字符串(%s)不符合格式(%s)!", fieldName, o, value);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
}
Date parse = DateUtil.parse(o, value);
String format = DateUtil.format(parse, value);
if (!format.equals(o)) {
// 禁用默认错误信息,防止错误信息与自定义信息乱串
constraintValidatorContext.disableDefaultConstraintViolation();
String message = String.format(Locale.CHINESE, "[%s]日期字符串(%s)有误,请检查!", fieldName, o);
constraintValidatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
}
return true;
}
}