感谢作者: http://www.spring4all.com/article/1225
当系统自带的注解无法满足我们的要求时候应该咋办呢?这就是本章将给各位介绍的自定义 Validator 注解
为何要自定义
javax.validation
包与 hibernate-validator
包中存在的注解几乎可以满足大部分的要求,又拥有基于正则表达式的@Pattern
,为什么还需要自己去定义呢?
- 正则效率不高
- 正则可读性不好
- 正则门槛较高,很多开发者并不会编写正则表达式
本章目标
熟悉 ConstraintValidator
接口并且编写自己的数据验证注解
自定义注解
这里定义了一个 @DateTime
注解,在该注解上标注了 @Constraint
注解,它的作用就是指定一个具体的校验器类
/**
* @author Ray
* @date 2018/7/4 0004
* 自定义注解
* FIELD 约束相关的属性;PARAMETER 约束相关的参数
*/
@Target({ElementType.FIELD, ElementType.PARAMETER}) // 约束注解应用的目标元素类型
@Retention(RetentionPolicy.RUNTIME) // 约束注解应用的时机
@Constraint(validatedBy = DateTimeValidator.class) // 与约束注解关联的验证器
public @interface DateTime {
/**
* 约束注解验证时的输出消息 - 关键字段
*/
String message() default "格式错误";
/**
* 约束注解验证时的格式
*/
String format() default "yyyy-MM-dd";
/**
* 约束注解在验证时所属的组别 - 关键字段
*/
Class<?>[] groups() default {};
/**
* 约束注解的有效负载 - 关键字段
*/
Class<? extends Payload>[] payload() default {};
}
具体验证
定义校验器类 DateTimeValidator
实现 ConstraintValidator
接口,实现接口后需要实现它里面的 initialize
与 isValid
方法。
/**
* @author Ray
* @date 2018/7/4 0004
* 日期格式验证
* 实现 initialize 与 isValid 方法
*/
public class DateTimeValidator implements ConstraintValidator<DateTime, String> {
private DateTime dateTime;
/**
* 主要用于初始化,它可以获得当前注解的所有属性
*/
@Override
public void initialize(DateTime dateTime) {
this.dateTime = dateTime;
}
/**
* 进行约束验证的主体方法,
* 其中 value 就是验证参数的具体实例,
* context 代表约束执行的上下文环境
*/
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 如果 value 为空则不进行格式验证,为空验证可以使用 @NotBlank @NotNull @NotEmpty 等注解来进行控制,职责分离
if(value == null){
return true;
}
String format = dateTime.format();
if(value.length() != format.length()){
return false;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
try{
simpleDateFormat.parse(value);
}catch (ParseException e){
return false;
}
return true;
}
}
控制层
/**
* @author Ray
* @date 2018/7/4 0004
* 参数校验
*/
@Validated
@RestController
public class ValidateController2 {
@GetMapping("/test")
public String test(@DateTime(message = "您输入的格式错误,正确的格式为:{format}", format = "yyyy-MM-dd") String date){
return "success";
}
}
测试
完成准备事项后,启动项目,自行测试即可,测试手段相信大伙都不陌生了,如 浏览器
、postman
、junit
、swagger
,此处基于 postman
>错误格式
>正确格式