一、定义一个校验注解,类似于@NotNull @Size等等那样
/**
* 枚举校验注解
*
* @author ye17186
* @version 2019/3/6 15:53
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValidator.class})
public @interface EnumValid {
String message() default "";
// 作用参考@Validated和@Valid的区别
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* 目标枚举类
*/
Class<?> target() default Class.class;
/**
* 是否忽略空值
*/
boolean ignoreEmpty() default true;
}
二、自定义枚举校验的处理类,该类必须实现ConstraintValidator接口
/**
* 枚举参数校验处理类
*
* @author ye17186
* @version 2019/3/6 15:56
*/
@Slf4j
public class EnumValidator 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();
boolean ignoreEmpty = annotation.ignoreEmpty();
// target为枚举,并且value有值,或者不忽视空值,才进行校验
if (cls.isEnum() && (StringUtils.isNotEmpty(value) || !ignoreEmpty)) {
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) {
log.warn("EnumValidator call isValid() method exception.");
result = false;
}
} else {
result = true;
}
return result;
}
}
三、代码中使用
1、定义一个枚举类
public enum TestEnum {
A, B, C
}
2、参数校验该枚举,注意接收参数类型必须为String,否则需要进行特殊处理才行
public class TestRequest implements Serializable {
private static final long serialVersionUID = -8739613309305982051L;
@EnumValid(target = TestEnum.class, message = "type取值必须为A, B, C")
private String type;
}
3、Controller中直接加上@Validated 或 @Valid即可
@RequestMapping("/test")
public ApiResp doSomething(@Validated @RequestBody TestRequest request) {
log.info("doSomething");
log.info(request.toString());
return ApiResp.retOK();
}