@Constraint自定义验证类型注解
Posted Java_小墨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了@Constraint自定义验证类型注解相关的知识,希望对你有一定的参考价值。
/**
* 银行卡校验
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {StringChecker.class, ObjectChecker.class})
public @interface BankCard {
String message() default "银行卡号格式错误";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* ConstraintValidator<A extends Annotation, T>
* A 第一个是自定义的注解类
* T 第二个就是要验证的数据的类型
* 例如写了String, 那么这个类只接收String类型的参数, 写了Long就接收Long类型的参数...
* 还可以写Object, 那么这个类就接收所有类型的参数, 可以用instanceof区分, 例子在下一个类
*/
class StringChecker implements ConstraintValidator<BankCard, String> {
/**
* 定义的银行卡号验证正则表达式
*/
private Pattern pattern = Pattern.compile("(^\\d{19}$)");
@Override
public void initialize(BankCard constraintAnnotation) {
// 初始化方法
System.out.println("StringChecker init");
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 验证的逻辑方法; 这里String类型的value 就是需要校验的对象, 它可能为空;
// 可以配合@NotNull, @NotBlank, @NotEmpty等来限制他是否为空
if (StringUtils.isEmpty(value)) {
return true;
}
Matcher matcher = pattern.matcher(value);
// matches精确匹配
return matcher.matches();
}
}
/**
* 接收@BankCard注解标注的字段, 由于是Object, 所以接收的类型不限
*/
class ObjectChecker implements ConstraintValidator<BankCard, Object> {
@Override
public void initialize(BankCard constraintAnnotation) {
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (null == value) {
return true;
}
// Object类型的value, 可以接收任何数据类型的数据
if (value instanceof String) {
System.out.println("它是String类型的值: " + value);
} else if (value instanceof Long) {
System.out.println("它是Long类型的值: " + value);
} // 等等...
return false;
}
}
}
在上面的这个自定义验证注解中,
@Constraint(validatedBy = StringChecker.class)
validatedBy里可以定义多个, 用{}括起来, 在这一行代码中, StringChecker类用来处理String类型的逻辑
这个内部类可以再外部定义, 这里是为了方便
class StringChecker implements ConstraintValidator<BankCard, String> {}
用@Constraint注解, 必须实现ConstraintValidator接口
里面有两个泛型, 第一个是自定义的注解类, 第二个是需要验证的数据类型, 可以用Object, 表示所有类型都支持, 根据不同类型走不同逻辑方法.
这个接口里面有两个方法, initialize和isValid.
第一个是初始化验证器, 初始化完成后的结果让isValid调用,
第二个是验证逻辑, 不同的逻辑方法就是在这里实现. 返回true, 则验证通过,false则不通过, 然后会抛出message里面自定义的异常信息。
另外:
这个自定义注解逻辑处理类由于实现了ConstraintValidator接口,所以它默认被spring管理成bean, 所以可以在这个逻辑处理类里面用@Autowiredu或者@Resources注入别的服务,而且不用在类上面用@Compent注解成spring的bean.
自定义验证类型注解类里面由于是用于验证数据,一般在里面加上
String message() default “用户不存在或者不属于当前组织”;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
备注:
- @Retention :用来说明该注解类的生命周期。它有以下三个参数:
- RetentionPolicy.SOURCE : 注解只保留在源文件中
- RetentionPolicy.CLASS : 注解保留在class文件中,在加载到JVM虚拟机时丢弃
- RetentionPolicy.RUNTIME : 注解保留在程序运行期间,此时可以通过反射获得定义在某个类上的所有注解。
- @Target : 用来说明该注解可以被声明在那些元素之前。
- ElementType.TYPE:说明该注解只能被声明在一个类前。
- ElementType.FIELD:说明该注解只能被声明在一个类的字段前。
- ElementType.METHOD:说明该注解只能被声明在一个类的方法前。
- ElementType.PARAMETER:说明该注解只能被声明在一个方法参数前。
- ElementType.CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前。
- ElementType.LOCAL_VARIABLE:说明该注解只能声明在一个局部变量前。
- ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前。
- ElementType.PACKAGE:说明该注解只能声明在一个包名前。
以上是关于@Constraint自定义验证类型注解的主要内容,如果未能解决你的问题,请参考以下文章