基元集合的 Hibernate 验证
我希望能够执行以下操作:
@Email
public List<String> getEmailAddresses()
{
return this.emailAddresses;
}
换句话说,我希望列表中的每个项目都被验证为电子邮件地址。当然,像这样注释集合是不可接受的。
有办法做到这一点吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
JSR-303 和 Hibernate Validator 都没有任何现成的约束来验证 Collection 的每个元素。
解决此问题的一种可能的解决方案是创建自定义
@ValidCollection
约束和相应的验证器实现ValidCollectionValidator
。为了验证集合的每个元素,我们需要在
ValidCollectionValidator
内有一个Validator
实例;为了获得这样的实例,我们需要自定义实现ConstraintValidatorFactory。看看您是否喜欢以下解决方案...
简单地,
ValidCollection
ValidCollectionValidator
ValidatorContextAwareConstraintValidator
CollectionElementBean
ConstraintValidatorFactoryImpl
员工
团队
ShoppingCart
ValidCollectionTest
输出
注意:- 当bean有约束时,不要指定
@ValidCollection
约束的 >constraints 属性。当 bean 没有约束时,constraints
属性是必需的。Neither JSR-303 nor Hibernate Validator has any ready-made constraint that can validate each elements of Collection.
One possible solution to address this issue is to create a custom
@ValidCollection
constraint and corresponding validator implementationValidCollectionValidator
.To validate each element of collection we need an instance of
Validator
insideValidCollectionValidator
; and to get such instance we need custom implementation ofConstraintValidatorFactory
.See if you like following solution...
Simply,
ValidCollection
ValidCollectionValidator
ValidatorContextAwareConstraintValidator
CollectionElementBean
ConstraintValidatorFactoryImpl
Employee
Team
ShoppingCart
ValidCollectionTest
Output
Note:- When bean has constraints do NOT specify the
constraints
attribute of@ValidCollection
constraint. Theconstraints
attribute is necessary when bean has no constraint.我没有足够高的声誉来对原始答案发表评论,但也许值得注意的是这个问题 JSR-308 正处于最终发布阶段,发布后将解决此问题!不过,它至少需要 Java 8。
唯一的区别是验证注释将位于类型声明内部。
请告诉我您认为我可以最好地将这些信息放在哪里,以供其他正在寻找的人使用。谢谢!
PS:如需了解更多信息,请查看这篇文章。
I don't have a high enough reputation to comment this on the original answer, but perhaps it is worth noting on this question that JSR-308 is in its final release stage and will address this problem when it is released! It will at least require Java 8, however.
The only difference would be that the validation annotation would go inside the type declaration.
Please let me know where you think I could best put this information for others who are looking. Thanks!
P.S. For more info, check out this SO post.
由于 Java 注解本身的限制,不可能编写像
@EachElement
这样的通用包装器注解来包装任何约束注解。但是,您可以编写一个通用约束验证器类,它将每个元素的实际验证委托给现有的约束验证器。您必须为每个约束编写一个包装器注释,但只需一个验证器。我已经在 jirutka/validator-collection (可在 Maven Central 中找到)中实现了这种方法。例如:
该库允许您轻松地为任何验证约束创建“伪约束”来注释简单类型的集合,而无需为每个集合编写额外的验证器或不必要的包装类。所有标准 Bean 验证约束和 Hibernate 特定约束都支持
EachX
约束。要为您自己的
@Awesome
约束创建@EachAwesome
,只需复制并粘贴注释类,将@Constraint
注释替换为@ Constraint(validatedBy = CommonEachValidator.class)
并添加注释@EachConstraint(validateAs = Awesome.class)
。就这样!编辑:针对当前版本的库进行了更新。
It’s not possible to write a generic wrapper annotation like
@EachElement
to wrap any constraint annotation — due to limitations of Java Annotations itself. However, you can write a generic constraint validator class which delegates actual validation of every element to an existing constraint validator. You have to write a wrapper annotation for every constraint, but just one validator.I’ve implemented this approach in jirutka/validator-collection (available in Maven Central). For example:
This library allows you to easily create a “pseudo constraint” for any validation constraint to annotate a collection of simple types, without writing an extra validator or unnecessary wrapper classes for every collection.
EachX
constraint is supported for all standard Bean Validation constraints and Hibernate specific constraints.To create an
@EachAwesome
for your own@Awesome
constraint, just copy&paste the annotation class, replace@Constraint
annotation with@Constraint(validatedBy = CommonEachValidator.class)
and add the annotation@EachConstraint(validateAs = Awesome.class)
. That’s all!EDIT: Updated for the current version of library.
感谢 becomputer06 的精彩回答。
但我认为应该将以下注释添加到 ValidCollection 定义中:
而且我仍然不明白如何处理原始类型包装器和约束注释(如 @Size、@Min、@Max 等)的集合,因为值不能通过becomputer06的方式。
当然,我可以为应用程序中的所有情况创建自定义约束注释,但无论如何我必须将这些注释的属性添加到 CollectionElementBean。这似乎是一个足够糟糕的解决方案。
Thanks for great answer from becomputer06.
But I think the following annotations should be added to ValidCollection definition:
And I still don't understant what to do with collections of primitive type wrappers and constrains annotations like @Size, @Min, @Max etc., because value can't be passed through becomputer06's way.
Of course, I can create custom contraint annotations for all cases in my application, but anyway I have to add properties for these annotations to CollectionElementBean. And it seems to be a bad enough solution.
JSR-303 能够扩展内置约束的目标类型:请参阅 7.1.2 。覆盖 XML 中的约束定义。
您可以实现一个
ConstraintValidator>
,它与给定的答案执行相同的操作,委托给原始验证器。然后,您可以保留模型定义并在List
上应用@Email
。JSR-303 has the ability to extend the target types of built in constraints: See 7.1.2. Overriding constraint definitions in XML.
You can implement a
ConstraintValidator<Email, List<String>>
which does the same thing as the given answers, delegating to the primitive validator. Then you can keep your model definition and apply@Email
onList<String>
.可以采用非常简单的解决方法。您可以改为验证包装简单值属性的类的集合。为此,您需要在集合上使用
@Valid
注释。示例:
A very simple workaround is possible. You can instead validate a collection of your classes that wrap the simple value property. For this to work you need to use
@Valid
annotation on the collection.Example: