昨天简单的介绍了小参数的一些基本的校验规则和使用方式,虽然已经可以解决大部分的参数校验,但是有时候有些特殊的校验还是无法直接实现,需要我们自定义去实现相关的校验。今天介绍下Validation的自定义校验方式,来实现一些特殊场景的参数校验。
1.自定义校验需要自行通过注解和实现 ConstraintValidator 接口进行实现,接下来我以一个简单的校验日志格式的方式案例来实现。
定义注解:
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateFormatCheckValidator.class) // 这个是具体的实现
@Documented
@Inherited
public @interface DateFormatCheckAnnotation {
/**
* 消息
*
* @return {@link String }
*/
String message() default "日期格式错误";
/**
* 组
* @return {@link Class }<{@link>{@link [] }
*/
Class>[] groups() default {};
/**
* 有效载荷
*
* @return {@link Class }<{@link link extends link payload>{@link [] }
*/
Class extends payload>[] payload() default {};
/**
* @return 返回日期格式 yyyy-MM-dd
*/
String dateFormat() default "yyyy-MM-dd";
}
其中 groups() 和 payload() 是固定的,如果不写则会报错
自定义实现
@Slf4j(topic = "DateFormatCheckValidator")
public class DateFormatCheckValidator implements ConstraintValidator {
/**
* 初始化
*
* @param constraintAnnotation 约束注释
*/
@Override
public void initialize(DateFormatCheckAnnotation constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}
/**
* 检查是否有效
*
* @param dateStr 日期str
* @param constraintValidatorContext 约束验证器上下文
* @return boolean
*/
@Override
public boolean isValid(String dateStr, ConstraintValidatorContext constraintValidatorContext) {
log.info("dateStr:{}", dateStr);
log.info("constraintValidatorContext:{}", constraintValidatorContext);
if(StrUtil.isBlank(dateStr)){
return false;
}
// 这里根据你的格式校验数据格式 格式 匹配 上了 配置的,
//则标识通过 返回true ,否则返回false
// 假设你的格式是 yyyy-MM-dd
// 这里校验 2024-06-24 是否符合你的格式
if (dateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
return true;
}
return false;
}
}
实体类等代码:
@Data
public class UserEntity implements Serializable {
private static final long serialVersionUID = 5966548219692983101L;
@NotBlank(message = "name can not be blank")
private String name;
@NotNull(message = "age 不能为空")
@Range(min = 1, max = 100, message = "年龄必须在1-100之间")
private Integer age;
@DateFormatCheckAnnotation(dateFormat = "yyyy-MM-dd", message = "日期格式不正确")
private String birthday;
}
// 接口实现
@RequestMapping("/index")
public Object index(@Valid UserEntity user) {
return user;
}
测试验证:
不写日期
日期格式填写不是注解配置的格式
在使用 Bean Validation(例如 Hibernate Validator)进行校验时,还可能遇到校验错误提示顺序并不是按照你期望的顺序的问题。由于Bean Validation 的默认行为是并不保证校验约束的执行顺序。所以你每次校验的时候看也能发现提示的内容都不是一致的,当然你可以通过分组的方式来进行控制(如果对顺序要求严格的话)
本文暂时没有评论,来添加一个吧(●'◡'●)