【问题标题】:Validating List nested in a Map with Hibernate Validator 5.2+使用 Hibernate Validator 5.2+ 验证嵌套在地图中的列表
【发布时间】:2016-05-13 06:44:34
【问题描述】:

我正在使用 Hibernate Validator 5.2,它支持 Java 8 type_use 注释。我希望能够在 Map 中验证 List 的内容——换句话说,我只希望它向下级联并验证 Map 和 List 的内容,无论它们是如何嵌套的。

一个简单的地图示例:

Map<String, List<Promotion>> promotionsByGroupName = ...;

我希望能够做到:

@Valid
Map<String, List<@Valid Promotion>> promotionsByGroupName = ...;

但是这不起作用,因为标准的 @Valid 注释不能放在该元素上。所以我创建了一个自定义注释,我可以放在那里:

@Valid
Map<String, List<@ValidPart Promotion>> promotionsByGroupName = ...;

但是,与 @ValidPart 关联的验证器永远不会被触发。

我设法得到的最接近的方法是将@ValidPart 注释放在 List 上,如下所示:

@Valid
Map<String, @ValidPart List<Promotion>> promotionsByGroupName = ...;

...然后在关联的验证器中解开列表以验证元素(不幸的是,这涉及在 ConstraintValidator 中调用验证器并“重写”生成的 ConstraintViolations)。

因此,我的问题是,有没有办法在不自己遍历列表的情况下进行这些嵌套验证?这生成的约束违反路径并不是我正在寻找的,因为它们看起来像:

promotionsByGroupName[GroupName].[0].name cannot be null

而不是(映射键名和索引之间没有点):

promotionsByGroupName[GroupName][0].name cannot be null

[0] 部分是我在此代码中使用 addPropertyName 添加自己的 List 的索引:

for (ConstraintViolation<?> violation : validator.validate(value)) {
    NodeBuilderCustomizableContext builder = context
        .buildConstraintViolationWithTemplate(violation.getMessage())
        .addPropertyNode("[" + i + "]");

    for (String nodeName : violation.getPropertyPath().toString().split("\\.")) {
        builder = builder.addPropertyNode(nodeName);
    }

    builder.addConstraintViolation();
}

【问题讨论】:

  • 我得出的结论是,在 ConstraintValidator 中调用 Validator 是无用的练习,因为失败的原始 ConstraintDescriptor 不能保留在新的约束违规中。看起来 JSR-303 规范适用于简单的人员/地址违规,但在用于复杂的现实世界数据结构时严重缺乏。滚动我自己的。

标签: java java-8 hibernate-validator


【解决方案1】:

暂时没有。 Hibernate Validator 目前不支持这种类型的嵌套展开。

【讨论】:

    【解决方案2】:

    作为一种变通方法,您可以创建一个特定的集合类型 Promotions,将其用作映射值,而不是 List&lt;Promotion&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多