validation自定义注解校验枚举类型

版权声明:原创欢迎转载,转载请注明出处 https://blog.csdn.net/ye17186/article/details/88242913

一、定义一个校验注解,类似于@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();
}

GitHub地址:https://github.com/ye17186/spring-boot-learn

猜你喜欢

转载自blog.csdn.net/ye17186/article/details/88242913