java validation内没有对枚举的校验工具,但是离散的枚举值校验确实是有必要的。javax.validation包提供了方便的自定义校验的入口,就是javax.validation.ConstraintValidator,故可以通过自定义校验枚举类型方式实现。
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EnumIntegerValidator.class})
@Documented
public @interface EnumIntegerValid {
String message() default "";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
Class>[] target() default {};
/**
* 允许的枚举
* @return
*/
Class extends Enum>> enumClass();
}
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* @description value值是Integer类型的枚举校验器
*/
public class EnumIntegerValidator implements ConstraintValidator {
private Class extends Enum> enumClass;
@Override
public void initialize(EnumIntegerValid enumIntegerValid) {
enumClass = enumIntegerValid.enumClass();
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
EnumValidate[] enums = (EnumValidate[]) enumClass.getEnumConstants();
if(enums ==null || enums.length == 0){
return false;
}
return enums[0].existValidate(value);
}
}
1、定义一个枚举值校验接口
/**
* @description 枚举值校验
*/
public interface EnumValidate {
/**
* 校验枚举值是否存在
*/
boolean existValidate(T value);
}
2、定义一个Integer类型枚举类
/**
* @description 测试类型枚举类
*/
public enum TestTypeEnum implements EnumValidate {
A(1, "测试A"),
B(2, "测试B");
private final Integer code;
private final String desc;
TestTypeEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return this.code;
}
public String getDesc() {
return this.desc;
}
@Override
public boolean existValidate(Integer value) {
if (value == null) {
return false;
}
for (TestTypeEnum testTypeEnum : TestTypeEnum.values()) {
if (testTypeEnum.getCode().intValue() == value.intValue()) {
return true;
}
}
return false;
}
}
3、参数校验该枚举,注意接收参数类型必须为Integer,否则使用String的枚举校验器。
public class TestRequest implements Serializable {
private static final long serialVersionUID = -8739613309305982051L;
@NotNull
@EnumIntegerValid(message = "测试类型输入错误", enumClass = TestTypeEnum.class)
private Integer type;
}
4、Controller中直接加上@Validated 或 @Valid即可
@RequestMapping("/test")
public ApiResponse doSomething(@Validated @RequestBody TestRequest request) {
log.info("doSomething");
log.info(request.toString());
return ApiResponse.retOK();
}
或:
private static Validator validator = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true)
.buildValidatorFactory()
.getValidator();
public static void validParam(T param) {
validParamNonNull(param);
Set> constraintViolations = validator.validate(param, Default.class);
StringBuilder sb = new StringBuilder();
if (constraintViolations != null && !constraintViolations.isEmpty()) {
for (ConstraintViolation constraintViolation : constraintViolations) {
sb.append(constraintViolation.getPropertyPath())
.append(":")
.append(constraintViolation.getMessage())
.append(".");
}
throw new IllegalArgumentException(sb.toString());
}
}
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EnumStringValidator.class})
@Documented
public @interface EnumStringValid {
String message() default "";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
Class>[] target() default {};
/**
* 允许的枚举
* @return
*/
Class extends Enum>> enumClass();
}
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* @description value值是String类型的枚举校验器
*/
public class EnumStringValidator implements ConstraintValidator {
private Class extends Enum> enumClass;
@Override
public void initialize(EnumStringValid enumStringValid) {
enumClass = enumStringValid.enumClass();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || "".equals(value)) {
return true;
}
EnumValidate[] enums = (EnumValidate[]) enumClass.getEnumConstants();
if(enums ==null || enums.length == 0){
return false;
}
return enums[0].existValidate(value);
}
}
/**
* 测试枚举类
*/
public enum TestEnum implements EnumValidate {
NONE("NONE", "无"),
C("C", "测试C");
private final String code;
private final String desc;
TestEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String getCode() {
return this.code;
}
public String getDesc() {
return this.desc;
}
@Override
public boolean existValidate(String value) {
if (value == null || "".equals(value)) {
return false;
}
for (TestEnum testEnum : TestEnum.values()) {
if (testEnum.getCode().equalsIgnoreCase(value)) {
return true;
}
}
return false;
}
}
public class TestRequest implements Serializable {
private static final long serialVersionUID = -8739613309305982051L;
@NotNull
@EnumStringValid(message = "测试类型输入错误", enumClass = TestEnum.class)
private String test;
}
参考:https://blog.csdn.net/lqadam/article/details/103446179?utm_source=distribute.pc_relevant.none-task
https://blog.csdn.net/ye17186/article/details/88242913