几个核心注解:
@Constraint 约束,指定当前注解用哪个类来处理
String message() default "参数校验不通过,请重新输入"; 这是后面验证不通过输出的消息,
代码实现
1、定义自定义注解
groups和payload也是必须添加的
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
//代表处理逻辑是MyConstraintValidator类
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {
String message() default "参数校验不通过,请重新输入";
long min();
long max();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2.处理类,需要实现ConstraintValidator接口
校验类需要实现ConstraintValidator接口。
接口使用了泛型,需要指定两个参数,第一个自定义注解类,第二个为需要校验的数据类型。
实现接口后要override两个方法,分别为initialize方法和isValid方法。其中initialize为初始化方法,可以在里面做一些初始化操作,isValid方法就是我们最终需要的校验方法了。可以在该方法中实现具体的校验步骤。isValid
方法里实现真正的校验逻辑,验证通过返回 true。第一个参数是
注解的对象,如果注解到类上,则对应类的对象。
constraintValidatorContext
是验证的上下文,可以将验证的结果存放在这里,如果验证不通过,错误信息也应该放在里面。
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, Object> {
private long max = 1;
private long min = 1;
@Override
public void initialize(MyConstraint constraintAnnotation) {
max = constraintAnnotation.max();
min = constraintAnnotation.min();
System.out.println("my validator init");
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
if(o == null){
return true;
}
if(o.toString().trim().length()>=min && o.toString().trim().length()<=max){
return true;
}
return false;
}
}
3.进行验证
3.1 定义一个实体类User
@Data
public class User {
@MyConstraint( min = 1, max =10 )
private String name;
private String address;
}
如果校验不通过,会产生BindException异常,捕捉到异常后可以获取到defaultMessage也就是自定义注解中定义的内容,
BindException ex = (BindException)e;
List<ObjectError> errors = ex.getAllErrors();
ObjectError error = errors.get(0);
String msg = error.getDefaultMessage();
Comments | NOTHING