简介:在入参的时候我们经常需要校验一些属性的值,是否在枚举中,就需要一个校验枚举的注解类。
一、枚举值校验注解类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 枚举值校验注解类
* @author xxxxxx
* @date
**/
@Documented
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR,PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = {EnumValidaAnnotation.EnumValidator.class})
public @interface EnumValidaAnnotation {
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<?>[] target() default {};
/** 枚举的判断属性名称,默认是Code */
String codeName() default "code";
/** 是否允许空字符串*/
boolean canBeEmpty() default false;
class EnumValidator implements ConstraintValidator<EnumValidaAnnotation, String> {
private static final Logger LOGGER = LoggerFactory.getLogger(EnumValidator.class);
Class<?>[] cls;
String name;
boolean canBeEmpty;
@Override
public void initialize(EnumValidaAnnotation constraintAnnotation) {
cls = constraintAnnotation.target();
name = constraintAnnotation.codeName();
canBeEmpty = constraintAnnotation.canBeEmpty();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (cls.length < 1 || value == null) {
return true;
}
if (canBeEmpty && value.isEmpty()){
return true;
}
for (Class<?> cl : cls) {
try {
if (cl.isEnum()) {
Object[] objs = cl.getEnumConstants();
Method method = cl.getMethod("get"+name.substring(0,1).toUpperCase()+name.substring(1));
for (Object obj : objs) {
Object code = method.invoke(obj, (Object[]) null);
if (code.toString().equals(value)) {
return true;
}
}
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
LOGGER.error("EnumValidator出错", e);
}
}
return false;
}
}
}
二、创建枚举,并使用注解校验。
import java.util.Objects;
/**
* xx类型枚举类
*
* @author xxxxxx
*/
public enum TrnTypeEnum {
A("A", "手动"),
M("M", "自动"),
;
private String code;
private String name;
public String getCode() {
return code;
}
public String getName() {
return name;
}
TrnTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
public static TrnTypeEnum getEnumByCode(String code) {
if (code == null) {
return null;
}
TrnTypeEnum[] values = TrnTypeEnum.values();
for (TrnTypeEnum value : values) {
if (Objects.equals(value.code, code)) {
return value;
}
}
return null;
}
}
public class UserDTO {
// canBeEmpty = true,代表入参可以为空
@EnumValidaAnnotation(target = TrnTypeEnum.calss, message = "xx类型不匹配", canBeEmpty = true)
private String trnType;
}