无法使用休眠验证器验证来自枚举的数据

时间:2019-06-27 07:17:57

标签: java

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

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)私有整数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());
        }
    }
}

1 个答案:

答案 0 :(得分:0)

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

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

valueList的实际值:[IMMEDIATE, SCHEDULED]
和值:来自正文有效载荷{"deliveryMethod": 8}的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
    }
}