自定义注解完成校验枚举类型的三种方法。
注解在实体类的字段上,要确定这个字段是什么类型。
有三种类型:
1、校验枚举类–自定义的各种Enum类型
2、校验枚举值–Integer类型
3、校验枚举名称–String类型
使用枚举涉及到前后端数据库类型转换的问题,相比之下,Integer和String使用简单。
校验枚举类–自定义的各种Enum类型
校验单一枚举类
仅仅作用于单个枚举类。
通过注解的实现类中,可以看到,该注解仅仅作用于Enum<GenderEnum>
枚举类。
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {GenderValidator.class})
public @interface GenderValid {
String message() default "Invalid GenderEnum type,请输入正确的枚举类型";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<?> target() default Class.class;
}
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* @author jjsai
* @date 2021/7/12 15:33
**/
public class GenderValidator implements ConstraintValidator<GenderValid, Enum<GenderEnum>> {
@Override
public void initialize(GenderValid constraintAnnotation) {
}
@Override
public boolean isValid(Enum<GenderEnum> value, ConstraintValidatorContext context) {
if (value instanceof GenderEnum) {
return true;
}
return false;
}
}
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.stream.Stream;
/**
* @author jjsai
* @date 2021/7/12 15:32
**/
public enum GenderEnum {
MALE(1,"男性"),
FEMALE(2,"女性"),
MONSTERS(3,"妖怪");
private Integer code;
private String desc;
GenderEnum(Integer code,String desc) {
this.code = code;
this.desc = desc;
}
@JsonValue
public Integer getCode() {
return code;
}
public String getDesc() {
return desc;
}
@JsonCreator
public static GenderEnum getGender(Integer code) {
if (code == null) {
return null;
}
GenderEnum[] values = GenderEnum.values();
return Stream.of(values).filter(it -> it.getCode().equals(code)).findAny().orElse(null);
}
}
@EnumValid
private GenderEnum gender;
校验各种枚举类
任何枚举类上都可以使用,需要传入参数target,指定哪个枚举类型。
通过注解的实现类中,可以看到,该注解作用于Object
类,任何枚举类都可以来这里校验。
import javax.validation.ConstraintValidatorContext;
/**
* @author jjsai
* @date 2021/7/12 11:43
**/
@Slf4j
public class EnumValidator implements ConstraintValidator<EnumValid, Object> {
private EnumValid annotation;
@Override
public void initialize(EnumValid constraintAnnotation) {
annotation = constraintAnnotation;
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
Class<?> cls = annotation.target();
Object[] objects = cls.getEnumConstants();
for (Object obj : objects) {
if (obj.equals(value)) {
return true;
}
}
return false;
}
}
@EnumValid(target = GenderEnum.class)
private GenderEnum gender;
@EnumValid(target = TypeEnum.class)
private TypeEnum type;
校验枚举值–Integer类型
通过注解的实现类中,可以看到,该注解作用于Integer
类。
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* @author jjsai
* @date 2021/7/12 11:43
**/
@Slf4j
public class EnumValidatorInteger implements ConstraintValidator<EnumValid, Integer> {
private EnumValid annotation;
@Override
public void initialize(EnumValid constraintAnnotation) {
annotation = constraintAnnotation;
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
boolean result = false;
// 获取注解时传的target参数
Class<?> cls = annotation.target();
if (cls.isEnum() && value != null ) {
// 获取这个枚举类中的枚举列表
Object[] objects = cls.getEnumConstants();
try {
for (Object obj : objects) {
// obj to Enum
// 这种方法些许潦草,可以使用反射,在下边
String s = JacksonUtils.obj2json(obj);
GenderEnum genderEnum = JacksonUtils.json2pojo(s, GenderEnum.class);
// 注解的字段值与枚举实例的code进行比较,一致 则校验通过
if (value.equals(genderEnum.getCode())) {
result = true;
break;
}
}
} catch (Exception e) {
result = false;
}
}
return result;
}
}
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Method;
/**
* @author jjsai
* @date 2021/7/12 11:43
**/
@Slf4j
public class EnumValidatorInteger implements ConstraintValidator<EnumValid, Integer> {
private EnumValid annotation;
@Override
public void initialize(EnumValid constraintAnnotation) {
annotation = constraintAnnotation;
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
boolean result = false;
// 获取注解时传的target参数
Class<?> cls = annotation.target();
if (cls.isEnum() && value != null ) {
// 获取这个枚举类中的枚举列表
Object[] objects = cls.getEnumConstants();
try {
// 获取枚举类中的getCode方法对象
Method method = cls.getMethod("getCode");
for (Object obj : objects) {
// obj对象反射调用getCode方法
Object code = method.invoke(obj);
// 注解的字段值与枚举实例的code进行比较,一致 则校验通过
if (value.equals(code)) {
result = true;
break;
}
}
} catch (Exception e) {
result = false;
}
}
return result;
}
}
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.stream.Stream;
/**
* @author jjsai
* @date 2021/7/12 15:32
**/
public enum GenderEnum {
MALE(1,"男性"),
FEMALE(2,"女性"),
MONSTERS(3,"妖怪");
private Integer code;
private String desc;
GenderEnum(Integer code,String desc) {
this.code = code;
this.desc = desc;
}
@JsonValue
public Integer getCode() {
return code;
}
public String getDesc() {
return desc;
}
@JsonCreator
public static GenderEnum getGender(Integer code) {
if (code == null) {
return null;
}
GenderEnum[] values = GenderEnum.values();
return Stream.of(values).filter(it -> it.getCode().equals(code)).findAny().orElse(null);
}
}
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jjsai
* @date 2021/7/11 19:05
**/
@Data
@NoArgsConstructor
public class Student {
private Long id;
private String userName;
private String telphone;
@EnumValid(target = GenderEnum.class)
private Integer gender;
}
校验枚举名称–String类型
通过注解的实现类中,可以看到,该注解作用于String
类。
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author jjsai
* @date 2021/7/12 11:43
**/
@Slf4j
public class EnumValidatorString implements ConstraintValidator<EnumValid, String> {
private EnumValid annotation;
@Override
public void initialize(EnumValid constraintAnnotation) {
annotation = constraintAnnotation;
}
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
boolean result = false;
Class<?> cls = annotation.target();
if (cls.isEnum() && (value != null && value.trim().length() != 0)) {
Object[] objects = cls.getEnumConstants();
try {
Method method = cls.getMethod("name");
for (Object obj : objects) {
Object code = method.invoke(obj);
if (value.equals(code.toString())) {
result = true;
break;
}
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
result = false;
}
}
return result;
}
}
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.stream.Stream;
/**
* @author jjsai
* @date 2021/7/12 15:32
**/
public enum GenderEnumString {
MALE(1, "男性"),
FEMALE(2, "女性"),
MONSTERS(3, "妖怪");
private Integer code;
private String desc;
GenderEnumString(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public String getDesc() {
return desc;
}
@JsonValue
public Integer getCode() {
return code;
}
@JsonCreator
public static GenderEnumString getGender(String desc) {
if (desc == null) {
return null;
}
GenderEnumString[] values = GenderEnumString.values();
return Stream.of(values).filter(it -> it.getDesc().equals(desc)).findAny().orElse(null);
}
}
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author jjsai
* @date 2021/7/11 19:05
**/
@Data
@NoArgsConstructor
public class Student {
private Long id;
private String userName;
private String telphone;
@EnumValid(target = GenderEnumString.class)
private String gender;
}