自己实现一个枚举validation校验器

背景

平时我们在进行接口校验的时候,我们会使用@Validation相关注解来帮助我们简化代码。其常用的注解其实已经能满足很大一部分需求,但是在进行枚举字段的接口校验的时候没有相关字段,尤其在我们不是使用枚举的name()方法来传递的时候,枚举的校验就需要很多类似的大段的方法来进行校验。而validation本身是提供了扩展的方法的,因此在次基础上实现了一个对枚举进行校验的注解。

基础类

1.EnumValidation注解

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;

/**
 * 自定义枚举验证注解
 */
@Documented
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EnumValidation.Validator.class})
public @interface EnumValidation {
    /**
     * 错误提示信息
     *
     * @return
     */
    String message() default "Enumeration validation failed";

    /**
     * 校验分组
     *
     * @return
     */
    Class<?>[] groups() default {};

    /**
     * 要检验参数所属的枚举数组
     *
     * @return
     */
    Class<? extends EnumType>[] enums();

    /**
     * 要校验的参数是否可以为空
     *
     * @return
     */
    boolean canBeBlank() default true;

    Class<? extends Payload>[] payload() default {};

    // 验证器内部类
    @Slf4j
    class Validator implements ConstraintValidator<EnumValidation, String> {

        Class<? extends EnumType>[] enums;
        boolean canBeBlank;

        @Override
        public void initialize(EnumValidation constraintAnnotation) {
            this.enums = constraintAnnotation.enums();
            this.canBeBlank = constraintAnnotation.canBeBlank();
        }

        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            //如果校验的字段为空,判断是否通过
            if (StringUtils.isBlank(value) || enums.length < 1) {
                return canBeBlank;
            }

            //校验枚举字段匹配
            for (Class<? extends EnumType> clazz : enums) {
                if (clazz.isEnum()) {
                    EnumType[] enumConstants = clazz.getEnumConstants();
                    for (EnumType enumType : enumConstants) {
                        if (value.equals(enumType.getValidKey())) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }
}

2.EnumType 枚举公共父类

/**
 * 枚举继承公共类
 */
public interface EnumType {

    /**
     * 获取key
     *
     * @return 获取key
     */
    String getValidKey();
}

使用方法

定义这两个类之后,我们只需要在我们定义的注解上继承EnumType,然后实现其getValidKey方法即可

如下:

/**
 * 是/否 枚举
 */
public enum YesOrNoEnum implements EnumType {
    NO(0, "否"),
    YES(1, "是"),
    ;

    YesOrNoEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public int code;
    public String desc;

    @Override
    public String getValidKey() {
        return code + "";
    }
}

然后在需要校验的字段上加上这个注解即可

import lombok.Data;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

/**
 * 人类
 *
 */
@Data
public class PersonDTO {
    @NotBlank(message = "姓名不能为空")
    @Size(max = 32, message = "姓名长度不能超过320")
    private String name;

    @NotNull(message = "年齡不能为空")
    @Range(min = 0, max = 150, message = "年龄必须在0-150之间")
    private Integer age;

    @EnumValidation(enums = YesOrNoEnum.class, canBeBlank = false, message = "错误的会员标志")
    private Integer memberFlag;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值