【问题标题】:Annotation based validation on DTO level happens before field level validation like @NotNull @Size etc基于 DTO 级别的注释验证发生在字段级别验证之前,例如 @NotNull @Size 等
【发布时间】:2020-10-21 07:22:29
【问题描述】:

我有一个 DTO 类,我在其中设置了一些必填字段。 并且,基于另一个类型字段,其中值可以假定为 A 和 B 如果是类型A,只需要检查一项可以通过,如果是B,也可以超过1项。

我需要检查一个列表在 DTO 类级别中是否至少有 1 个值。而且,在自定义注释验证中,我需要根据 DTO 的类型字段检查列表的大小。

所以,在 DTO 中

@NotNull
@Size(min = 1)
private List<@NotBlank String> items;

而且,在注解内

        if (cancelType == CancellationTypeEnum.A && cancelDto.getItems().size() > 1) {

            isValid = false;
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(
                    "Only one item can be sent for 'A' cancel type.").addConstraintViolation();

        } 

但是,由于字段级别稍后发生,如果我为 items 字段传递 null,它会转到此注释验证器并抛出 NPE,因为字段为 null 并且我正在尝试获取大小

临时解决方案是我先进行空值检查,然后检查大小,但无论如何在字段级别我们都会给出@NotNull。

有没有办法在字段级验证发生后进行类级自定义注释进行验证。 在这种情况下,它将抛出字段级别验证,因为字段为 null 并且不会转到自定义类级别注释

【问题讨论】:

    标签: java spring-boot hibernate-validator spring-validator


    【解决方案1】:

    您可以结合文档中的@Validated 使用 JS-303 验证组(请参阅 here):

    JSR-303的Valid的变种,支持validation的规范 组。

    例如:

    @CheckEnumSize(groups = {Secondary.class})
    public class CancelDto {
    
        public CancelDto(List<String> items) {
            this.items = items;
        }
    
        @NotNull(groups = {Primary.class})
        @Size(min = 1)
        public List<@NotNull String> items;
    
        public CancellationTypeEnum cancelType;
    
        public List<String> getItems() {
            return items;
        }
    }
     
    

    Primary 是一个简单的接口:

    public interface Primary {
    }
    

    Secondary 也一样:

    public interface Secondary {
    }
    

    最后你可以按如下方式使用验证:

    @Service
    @Validated({Primary.class, Secondary.class})
    public class CancelService {
    
        public void applyCancel(@Valid CancelDto cancel) {
            //TODO
        }
    
    }
    

    当使用上面的代码和 CancelDto 并且项目为空时,你应该得到:

    Caused by: javax.validation.ConstraintViolationException: applyCancel.cancel.items: must not be null
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多