【问题标题】:Not able to validate data from enum using hibernate validator无法使用休眠验证器验证来自枚举的数据
【发布时间】:2019-06-27 07:17:57
【问题描述】:

我正在使用休眠验证器来验证 DTO 对象。这里面临一个挑战,无法检查枚举中的数据是否可用 我用过下面的枚举

public enum DeliveryMethodEnum {
    IMMEDIATE(1), 
    SCHEDULED(2);

    private Integer deliveryMethod;

    private DeliveryMethodEnum(Integer deliveryMethod) {
        this.deliveryMethod = deliveryMethod;
    }

    public Integer getDeliveryMethod() {
        return deliveryMethod;
    }
}

在 DTO 中使用如下自定义注释

@EnumValidator(message = "1008", enumClass = DeliveryMethodEnum.class) private Integer deliveryMethod;

Request is below
{
    "deliveryMethod": 8
}

它应该显示无效请求,但它没有从枚举中验证。

我有以下客户注释代码

@Documented
@Constraint(validatedBy = EnumValidatorImpl.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@NotNull(message = "Value cannot be null")
@ReportAsSingleViolation
public @interface EnumValidator {

    Class<? extends Enum<?>> enumClass();

    String message() default "Value is not valid";

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

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

}


public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, Integer> {

    List<String> valueList = null;

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return !valueList.contains(String.valueOf(value));
    }

    @Override
    public void initialize(EnumValidator constraintAnnotation) {
        valueList = new ArrayList<>();
        Class<? extends Enum<?>> enumClass = constraintAnnotation.enumClass();

        @SuppressWarnings("rawtypes")
        Enum[] enumValArr = enumClass.getEnumConstants();

        for (@SuppressWarnings("rawtypes")
        Enum enumVal : enumValArr) {
            valueList.add(enumVal.toString().toUpperCase());
        }
    }
}

【问题讨论】:

    标签: java


    【解决方案1】:

    这是因为您的 EnumValidatorImpl 类中存在错误。
    下面一行

    !valueList.contains(String.valueOf(value));
    

    valueList的实际值:[IMMEDIATE, SCHEDULED]
    和值:来自正文有效负载的 8 {"deliveryMethod": 8}
    所以验证总是会失败。
    同样!valueList.contains 这对于非枚举值有效, 如果您只需要验证枚举值,请删除 ! 符号。

    解决方案
    1. 接受来自请求的字符串作为

    {
        "deliveryMethod": "IMMEDIATE"
    }
    
    or
    
    {
        "deliveryMethod": "SCHEDULED"
    }
    

    因此需要更新DTO,现在值是枚举/非枚举之一并得到验证

    1. 将 valueList 创建为 [1, 2] 并验证。

    这里是更新的 EnumValidatorImpl.java

    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, Integer> {
    
        List<Integer> valueList = null;
    
        @Override
        public boolean isValid(Integer value, ConstraintValidatorContext context) {
            return valueList.contains(value);
        }
    
        @Override
        public void initialize(EnumValidator constraintAnnotation) {
            valueList = new ArrayList<>();  
            Class<? extends Enum<?>> enumClass = constraintAnnotation.enumClass();
    
            Enum[] enumValArr = enumClass.getEnumConstants();
            valueList = Arrays.stream(enumValArr)
                    .map(anEnum -> ((DeliveryMethodEnum) anEnum).deliveryMethod)
                    .collect(Collectors.toList()); // This will make problem, since it will only be used for DeliveryMethodEnum enum type and not for any other enum, if it is not the problem then this can be done,else  I could not think of any other way
        }
    }
    
    

    【讨论】:

    • 如何将值列表创建为 ["1", "2"]?
    • 这是您需要弄清楚的另一个问题。参考:stackoverflow.com/a/29465971/2987755
    • 有没有办法从枚举值中检查值?
    • @ShiladittyaChakraborty 更新了答案,但 ((DeliveryMethodEnum) anEnum).deliveryMethod) 使其成为非通用注释。
    猜你喜欢
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    相关资源
    最近更新 更多