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

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

回答: 在Spring Validation中,你可以使用自定义注解来定义校验规则。在引用中的代码中,我们可以看到`@BankNo`注解的定义。这个注解标识了一个银行账号的校验规则。通过`validatedBy`属性指定了具体的校验逻辑的实现类`BankNoValidator`。同时,`groups`和`payload`属性可以用于对校验进行分类和负载。在引用中的代码中,我们可以看到在接口或方法中使用`@Validated`注解来启用校验功能。在例子中,`OrderDTO`对象上使用了`@Validated`注解,表示要对这个对象进行校验。而在引用中的代码中,我们可以看到`EqualsXzhValidator`类实现了`ConstraintValidator<EqualsXzh, String>`接口,其中`EqualsXzh`注解是自定义的注解,用于校验字符串必须是"xzh"。自定义校验规则的实现逻辑写在`isValid`方法中,根据具体的业务需求来编写校验规则。这样,在使用`@Validated`注解进行校验时,就会自动触发对应的校验规则。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Spring自定义注解(validation)](https://blog.csdn.net/ileopard/article/details/123485111)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [基于Spring Validation自定义校验注解](https://blog.csdn.net/Anenan/article/details/128004111)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值