1.校验注解
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* 校验枚举值
*
* @author tgj
*/
@Documented
@Constraint(validatedBy = O3EnumValidation.class)
@Target({
ElementType.TYPE
, ElementType.FIELD
, ElementType.METHOD
, ElementType.PARAMETER
, ElementType.CONSTRUCTOR
, ElementType.LOCAL_VARIABLE
, ElementType.PACKAGE
})
@Retention(RetentionPolicy.RUNTIME)
public @interface O3Enum {
String message() default "值超出范围 {enumValue}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};//负载
long[] intEnum() default {};
double[] floatEnum() default{};
boolean[] boolEnum() default {};
String[] strEnum() default {};
@Target({
ElementType.TYPE
, ElementType.FIELD
, ElementType.METHOD
, ElementType.PARAMETER
, ElementType.CONSTRUCTOR
, ElementType.LOCAL_VARIABLE
, ElementType.PACKAGE
, ElementType.ANNOTATION_TYPE
})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
O3Enum[] value();
}
}
2.校验器
import com.alibaba.fastjson.JSON;
import com.hizima.zimacs.serve.common.pojo.Bool;
import com.hizima.zimacs.serve.common.util.ArrayUtil;
import javax.validation.ConstraintValidatorContext;
import java.util.*;
/**
* 枚举值校验器
*
* @author tgj
*/
public class O3EnumValidation extends O3Validator<O3Enum, Object> {
private Set<Object> enumSet;
public O3EnumValidation(Set<Object> enumSet) {
this.enumSet = enumSet;
}
@Override
public void initialize(O3Enum constraintAnnotation) {
this.enumSet=new HashSet<>();
this.enumSet.addAll(ArrayUtil.aryToList(constraintAnnotation.intEnum()));
this.enumSet.addAll(ArrayUtil.aryToList(constraintAnnotation.floatEnum()));
this.enumSet.addAll(ArrayUtil.aryToList(constraintAnnotation.boolEnum()));
this.enumSet.addAll(ArrayUtil.aryToList(constraintAnnotation.strEnum()));
}
@Override
protected void addValidateLogic(Object val, ConstraintValidatorContext context, Bool isSuccess, StringJoiner stringJoiner) {
if (!enumSet.contains(val)){
isSuccess.setFalse();
stringJoiner.add(val+" 超出范围 :"+ JSON.toJSONString(enumSet));
}
}
}
3.注解可放置的位置
ElementType.TYPE:能修饰类、接口或枚举类型
ElementType.FIELD:能修饰成员变量
ElementType.METHOD:能修饰方法
ElementType.PARAMETER:能修饰参数
ElementType.CONSTRUCTOR:能修饰构造器
ElementType.LOCAL_VARIABLE:能修饰局部变量
ElementType.ANNOTATION_TYPE:能修饰注解
ElementType.PACKAGE:能修饰包
4.注解在不同位置validation传入的值
ElementType.TYPE:注解在类上,传入的是该类的实例
ElementType.FIELD:注解在属性上,传入的是该属性的值
ElementType.METHOD:注解在方法上,传入的是该方法的返回值
ElementType.PARAMETER:注解在方法的入参上,传入的是被注解的入参
ElementType.CONSTRUCTOR:貌似不会触发校验
ElementType.LOCAL_VARIABLE:貌似不会触发校验
ElementType.ANNOTATION_TYPE:貌似不会触发校验
ElementType.PACKAGE:未测试
5.其他
关于包的注解如下图:
关于自定义校验注解注解list等集合类型的属性、反参、入参时,是否遍历集合
不会,校验器中的入参是集合类型,而不是集合的泛型。
关于@Validated注解局部变量是否生效
@Validated只能注解普通类、方法、方法入参,不能注解局部变量。要校验局部变量,使用如下代码:
Validation.buildDefaultValidatorFactory().getValidator().validate(校验对象,Class<?>... 校验分组)
关于@Validated注解list等集合类型的入参时,是否遍历集合进行校验
不会遍历集合,需要自定义注解进行拦截校验。