validation自定義註解校驗枚舉類型

        java validation內沒有對枚舉的校驗工具,但是離散的枚舉值校驗確實是有必要的。javax.validation包提供了方便的自定義校驗的入口,就是javax.validation.ConstraintValidator,故可以通過自定義校驗枚舉類型方式實現。

一、定義一個校驗註解,類似於@NotNull @Size等等那樣

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

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EnumIntegerValidator.class})
@Documented
public @interface EnumIntegerValid {

    String message() default "";

    Class<?>[] groups() default {};

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

    Class<?>[] target() default {};

    /**
     * 允許的枚舉
     * @return
     */
    Class<? extends Enum<?>> enumClass();

}

二、自定義枚舉校驗的處理類,該類必須實現ConstraintValidator接口

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @description value值是Integer類型的枚舉校驗器
 */
public class EnumIntegerValidator implements ConstraintValidator<EnumIntegerValid,Integer> {

    private Class<? extends Enum> enumClass;

    @Override
    public void initialize(EnumIntegerValid enumIntegerValid) {
        enumClass = enumIntegerValid.enumClass();
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }

        EnumValidate[] enums = (EnumValidate[]) enumClass.getEnumConstants();
        if(enums ==null || enums.length == 0){
            return false;
        }

        return enums[0].existValidate(value);
    }
}

三、代碼中使用

1、定義一個枚舉值校驗接口

/**
 * @description 枚舉值校驗
 */
public interface EnumValidate<T> {

    /**
     * 校驗枚舉值是否存在
     */
    boolean existValidate(T value);

}

2、定義一個Integer類型枚舉類

/**
 * @description 測試類型枚舉類
 */
public enum TestTypeEnum implements EnumValidate<Integer> {
    A(1, "測試A"),
    B(2, "測試B");

    private final Integer code;
    private final String desc;

    TestTypeEnum(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public Integer getCode() {
        return this.code;
    }

    public String getDesc() {
        return this.desc;
    }

    @Override
    public boolean existValidate(Integer value) {
        if (value == null) {
            return false;
        }
        for (TestTypeEnum testTypeEnum : TestTypeEnum.values()) {
            if (testTypeEnum.getCode().intValue() == value.intValue()) {
                return true;
            }
        }
        return false;
    }
}

3、參數校驗該枚舉,注意接收參數類型必須爲Integer,否則使用String的枚舉校驗器。

public class TestRequest implements Serializable {
 
    private static final long serialVersionUID = -8739613309305982051L;
 
    @NotNull
    @EnumIntegerValid(message = "測試類型輸入錯誤", enumClass = TestTypeEnum.class)
    private Integer type;
	
}

4、Controller中直接加上@Validated 或 @Valid即可

@RequestMapping("/test")
public ApiResponse doSomething(@Validated @RequestBody TestRequest request) {
    log.info("doSomething");
    log.info(request.toString());
    return ApiResponse.retOK();
}

或:

private static Validator validator = Validation.byProvider(HibernateValidator.class)
        .configure()
        .failFast(true)
        .buildValidatorFactory()
        .getValidator();

public static <T> void validParam(T param) {
    validParamNonNull(param);
    Set<ConstraintViolation<T>> constraintViolations = validator.validate(param, Default.class);
    StringBuilder sb = new StringBuilder();
    if (constraintViolations != null && !constraintViolations.isEmpty()) {
        for (ConstraintViolation<T> constraintViolation : constraintViolations) {
            sb.append(constraintViolation.getPropertyPath())
                .append(":")
                .append(constraintViolation.getMessage())
                .append(".");
        }
        throw new IllegalArgumentException(sb.toString());
    }
}

四、對於String類型的枚舉類

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

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EnumStringValidator.class})
@Documented
public @interface EnumStringValid {

    String message() default "";

    Class<?>[] groups() default {};

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

    Class<?>[] target() default {};

    /**
     * 允許的枚舉
     * @return
     */
    Class<? extends Enum<?>> enumClass();

}
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @description value值是String類型的枚舉校驗器
 */
public class EnumStringValidator implements ConstraintValidator<EnumStringValid,String> {

    private Class<? extends Enum> enumClass;

    @Override
    public void initialize(EnumStringValid enumStringValid) {
        enumClass = enumStringValid.enumClass();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null || "".equals(value)) {
            return true;
        }

        EnumValidate[] enums = (EnumValidate[]) enumClass.getEnumConstants();
        if(enums ==null || enums.length == 0){
            return false;
        }

        return enums[0].existValidate(value);
    }
}
/**
 * 測試枚舉類
 */
public enum TestEnum implements EnumValidate<String> {
    NONE("NONE", "無"),
    C("C", "測試C");

    private final String code;
    private final String desc;

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

    public String getCode() {
        return this.code;
    }

    public String getDesc() {
        return this.desc;
    }

    @Override
    public boolean existValidate(String value) {
        if (value == null || "".equals(value)) {
            return false;
        }

        for (TestEnum testEnum : TestEnum.values()) {
            if (testEnum.getCode().equalsIgnoreCase(value)) {
                return true;
            }
        }
        return false;
    }

}
public class TestRequest implements Serializable {
 
    private static final long serialVersionUID = -8739613309305982051L;
 
    @NotNull
    @EnumStringValid(message = "測試類型輸入錯誤", enumClass = TestEnum.class)
    private String test;
	
}

 

參考:https://blog.csdn.net/lqadam/article/details/103446179?utm_source=distribute.pc_relevant.none-task

https://blog.csdn.net/ye17186/article/details/88242913

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章