【发布时间】: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