首页 > 解决方案 > 在春季请求中验证枚举

问题描述

我有一个请求WorkerRequest,其中有一个enumwhich has FULL_TIMEMANAGER依此类推。

WorkerRequest如何在此枚举上应用长度验证?

示例:枚举类型不应大于 8 个字符。

FULL_TIME有效(8 个字符)

PERMANENT无效(9 个字符)

目前,如果我把javax.validation.constraints.Size

  @Size(min = 0, max = 8, message = "Allowed length for workerType is 8.")
  @Enumerated(EnumType.STRING)
  private WorkerType workerType;

它抛出一个错误:

HV000030:找不到约束“javax.validation.constraints.Size”验证类型“com.XX.XX.XX.WorkerType”的验证器。检查“workerType”的配置

标签: javaspringvalidationspring-bootenums

解决方案


@Size、@Length 和 @Column(length=value) 之间的差异中所述

@Size是一个 Bean Validation 注解,用于验证关联的String是否具有长度受最小值和最大值限制的值。

您只能指定在数据库中持久化枚举值所需的最大长度。例如,如果您定义@Column(length = 8)而不是 @Size,您将workerType VARCHAR(8)在您的数据库定义中看到相应的。

但是有一个解决方法:假设你有

 public enum WorkerType {PERMANENT , FULL_TIME, ...}; 
  1. 定义一个自定义验证注解:

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = EnumSizeLimit.class)
    public @interface EnumSizeLimit {
        String message() default "{com.example.app.EnumSizeLimit.message}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
        Class<? extends Enum<?>> targetClassType();
    }
    
  2. 实现一个验证器:

    public class EnumSizeLimitValidator implements ConstraintValidator < EnumSizeLimit , String > {
         private Set < String > allowedValues;
    
         @SuppressWarnings({
             "unchecked",
             "rawtypes"
         })
        @Override
        public void initialize(EnumSizeLimit targetEnum) {
        Class << ? extends Enum > enumSelected = targetEnum.targetClassType();
        allowedValues = (Set < String > ) EnumSet.allOf(enumSelected).stream().map(e - > ((Enum << ? extends Enum << ? >> ) e).name())
            .collect(Collectors.toSet());
        }
    
        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            return value == null || (value.length>=0 && value.length<=8)) ? true : false;
        }
    }
    
  3. 定义字段:

    @EnumSizeLimit (targetClassType = WorkerType.class, message = "your message" 
    private String workerType; 
    

推荐阅读