SpringBoot EnumValidator驗證器實現


實現背景

在實際開發過程中,往往也需要對某些參數進行枚舉合法值校驗。如果在代碼中大量充斥者if else check代碼,實現不夠優雅。借鑒Hibernate其他優秀驗證器的實現,Enum校驗也可以擁有自己的驗證器!

 

實現原理

1. 定義枚舉檢查注解@EnumCheck,方便在請求對象參數上使用;

2. 定義接口EnumValidator,讓需要驗證的Enum類實現getValue()方法,主要目的是獲取枚舉的比較值;

3. 實現接口ConstraintValidator的isValid()方法,實現具體的枚舉校驗邏輯。

 

代碼實現

1. @EnumCheck注解類:

/**
 * 枚舉檢查注解
 *
 * @author binglang
 * @date 2021/8/31 11:41
 */
@Documented
@Constraint(validatedBy = EnumConstraintValidator.class)
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(EnumCheck.List.class)
public @interface EnumCheck {
    /**
     * 提示信息
     *
     */
    String message() default "{javax.validation.constraints.EnumCheck.message}";

    /**
     * 分組
     *
     */
    Class<?>[] groups() default { };

    /**
     * 擴展對象
     *
     */
    Class<? extends Payload>[] payload() default { };

    /**
     * 必須實現EnumValidator接口的枚舉類
     *
     */
    Class<? extends EnumValidator> clazz();

    /**
     * 調用的方法名稱
     */
    String method() default "getValue";

    /**
     * Defines several {@code @In} constraints on the same element.
     *
     * @see EnumCheck
     */
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        /**
         * In數組
         */
        EnumCheck[] value();
    }
}

 

2. EnumValidator接口定義:

/**
 * 枚舉驗證接口
 *
 * @author binglang
 * @date 2021/8/31 11:43
 */
public interface EnumValidator {
    Object getValue();
}

 

3. EnumConstraintValidator驗證器具體實現:

/**
 * 枚舉驗證器實現
 *
 * @author binglang
 * @date 2021/8/31 11:44
 */
public class EnumConstraintValidator implements ConstraintValidator<EnumCheck, Object> {
    /**
     * 注解對象
     */
    private EnumCheck annotation;

    /**
     * 初始化方法
     *
     * @param constraintAnnotation 注解對象
     */
    @Override
    public void initialize(EnumCheck constraintAnnotation) {
        this.annotation = constraintAnnotation;
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (Objects.isNull(value)) {
            return false;
        }

        Object[] enumConstants = annotation.clazz().getEnumConstants();
        try {
            // 核心代碼實現
            Method method = annotation.clazz().getMethod(annotation.method());
            for (Object enumConstant : enumConstants) {
                if (value.equals(method.invoke(enumConstant))) {
                    return true;
                }
            }
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }

        return false;
    }
}

 

如何使用

1. 需要校驗的枚舉類實現上面的EnumValidator接口:

/**
 * 引用節點類型
 *
 * @author binglang
 * @date 2021/7/13 20:12
 */
public enum RefNodeType implements EnumValidator {
    FIELD("field", "field"),
    FUNC("func", "func");

    private final String code;
    private final String label;

    RefNodeType(String code, String label) {
        this.code = code;
        this.label = label;
    }

    public String getCode() {
        return code;
    }

    public String getLabel() {
        return label;
    }

    // 實現getValue()邏輯
    @Override
    public Object getValue() {
        return code;
    }

 

2. 請求對象使用@EnumCheck注解:

@Data
public class TestDto {
    @ApiModelProperty(value = "變量類型")
    @NotBlank(message = "變量類型不能為空")
    @EnumCheck(clazz = RefNodeType.class, message = "變量類型不合法")
    private String refNodeType;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM