spring-boot-starter-validation和javax.validation提供了一些常用的注解如@NotBlank @Max @Min @NotEmpty @NotNull @Email,优雅的实现了对请求参数的校验,但有时请求参数可能是枚举类型的值,就需要对值的合法性进行校验,我们可以通过实现ConstraintValidator接口自定义枚举类型校验器。
话不多说,直接上代码
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
自定义枚举校验注解Enum.java
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 = {EnumValidtor.class})
@Documented
public @interface Enum {
/**
* 枚举的类型
*/
Class<?> value();
/**
* 错误消息
*
* @return
*/
String message();
/**
* 获取枚举值的方法
*/
String method() default "getCode";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
自定义枚举类型校验器
EnumValidtor.java
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* 枚举类型字段校验
*/
public class EnumValidtor implements ConstraintValidator<Enum, String> {
/**
* 枚举的值
*/
private final List<String> values = new ArrayList();
@Override
public void initialize(Enum constraintAnnotation) {
Class<?> enumClazz = constraintAnnotation.value();
Object[] enumConstants = enumClazz.getEnumConstants();
if (null == enumConstants) {
return;
}
Method method;
try {
method = enumClazz.getMethod(constraintAnnotation.method());
} catch (Exception e) {
throw new RuntimeException("枚举未找到方法"+constraintAnnotation.method(), e);
}
if (null == method) {
throw new RuntimeException("枚举未找到方法"+constraintAnnotation.method());
}
method.setAccessible(true);
try {
for (Object enumConstant : enumConstants) {
values.add(method.invoke(enumConstant).toString());
}
} catch (Exception e) {
throw new RuntimeException("获取枚举值失败", e);
}
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return null == value || values.contains(value);
}
}
自定义枚举校验注解使用示例
@Getter
@AllArgsConstructor
public enum CustomerTypeEnum {
TYPE_1("01", "金融机构"),
TYPE_2("02", "企业"),
TYPE_3("03", "事业单位"),
TYPE_6("06", "个体工商户"),
TYPE_4("04", "个人"),
TYPE_9("09", "其他"),
;
/**
* 客户类型编码
*/
private String code;
/**
* 客户类型名称
*/
private String name;
}
public class CustomerAo {
/**
* 登记类型
*/
@Enum(value = CustomerTypeEnum.class/*, method = "getCode" 与CustomerTypeEnum获取枚举值方法对应*/, message = "客户类型不合法")
@NotBlank(message = "客户类型不能为空")
private String customerType;
}