首先,我们先看一下valid自带的长度校验Length的源码,我将下面源码的注解作出一定的解释
// 指示注解应该记录在生成的Javadoc中,确保自定义注解在生成的文档中可见,便于了解其功能和用途
@Documented
// 指定用于验证该注解的验证器类,之后我们把自定义的校验器类名写在这里即可
@Constraint(
validatedBy = {}
)
// 指定注解可以应用的Java元素类型
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
// 指定注解的保留策略,此处为“运行时保留”,还有“编译时保留”和“只在源码中存在”
@Retention(RetentionPolicy.RUNTIME)
使注解可以在同一个元素上多次应用
@Repeatable(List.class)
public @interface Length {
int min() default 0;
int max() default Integer.MAX_VALUE;
String message() default "{org.hibernate.validator.constraints.Length.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
Length[] value();
}
}
上面代码所提到的@Repeatable注解大致作用如下:
public class Example {
@Valid("check1")
@Valid("check2")
private String field;
}
看完validation自带的长度校验之后,我们自己实现一个字符串开头字符为'a'的校验:
- 首先,先自定义一个校验注解
@Documented // 这个里面的StartWithAValidation.class就是我们第二步将要写的自定义校验器 @Constraint( validatedBy = StartWithAValidation.class ) @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(StartWithA.List.class) public @interface StartWithA { String message() default "不是以‘a’开头的"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface List { StartWithA[] value(); } }
- 我们开始实现一个自定义校验器类,这个校验器类需要实现ConstraintValidator接口,然后实现接口的isValid方法,代码如下:
public class StartWithAValidation implements ConstraintValidator<StartWithA,String> { @Override public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) { // 这里面写一些校验规则 if(s.charAt(0) == 'a'){ return true; } return false; } }
- 之后在我们所需要校验的实体类里面添加校验注解:
@StartWithA private String functions;
-
最后,在接受校验数据的接口参数部分添加@Valided注解,因为我的functions字段在TaskReqVo中,所以在这个接口参数中添加注解即可
public ResponseData save(@RequestBody @Validated TaskReqVo taskReqVo){ return ResponseData.success(taskService.saveTask(taskReqVo)); }
-
如果格式不对则会在后端日志出现以下提醒
以上便是自定义校验器的实现步骤,欢迎大家提出自己的见解!!!