【问题标题】:How to use Java Bean Validators (JSR-303/JSR-349) on elements of an array/list/collection如何在数组/列表/集合的元素上使用 Java Bean 验证器 (JSR-303/JSR-349)
【发布时间】:2013-12-21 11:15:27
【问题描述】:

我是使用 Java Bean 验证 (JSR-303/JSR-349/Hibernate Validator) 的新手,并且了解一般概念。但是,我不确定如何验证组合类型的内容与类型本身。

例如:

@NotNull
private List<String> myString;

将验证 List myString 不为空,但不验证列表本身的内容。或者给定其他类型的验证器(最小/最大/等),我如何验证列表的各个元素?是否有任何组合类型的通用解决方案?

【问题讨论】:

    标签: java validation bean-validation


    【解决方案1】:

    从 Bean Validation 1.0/1.1 开始,没有简单的通用解决方案。你可以实现一个自定义约束,比如@NoNullElements:

    @NoNullElements
    private List<String> myStrings;
    

    约束的验证器将遍历列表并检查没有元素为空。另一种方法是将您的 String 包装成更特定于域的类型:

    public class EmailAddress {
    
        @NotNull
        @Email
        private String value;
    
        //...
    }
    

    并通过@Valid 对列表应用级联验证:

    @Valid
    private List<EmailAddress> addresses;
    

    拥有这种特定于域的数据类型通常有助于在数据元素通过应用程序时传达其含义。

    将来,该问题的通用解决方案可能是在 Java 8 支持的类型参数上使用注释,但目前这只是一个想法:

    private List<@NotNull String> myStrings;
    

    【讨论】:

    • 谢谢!这几乎也是我想出的,但是我希望会有对聚合构造的内置支持,但显然缺少了。
    • List&lt;@NotNull String&gt; 在 Hibernate Validator 5.x 的最新版本中作为专有功能得到支持,并将成为 Bean Validation 2.0 规范的官方部分。
    【解决方案2】:

    看看validator-collection——通过这个库在简单类型的集合上使用任何约束注解都非常容易。另见https://stackoverflow.com/a/16023061/2217862

    【讨论】:

    • 感谢分享。肯定会仔细研究一下,但看起来很有希望。
    【解决方案3】:

    即将推出的 jsr 380(bean 验证 2.0)将允许将约束注释添加到参数类型。

    @有效 私有列表 myString;

    现在,您可以在 Bean Validation 1.1 中创建检查 null 条件的自定义约束。

    【讨论】:

    • 这里不需要@Valid注解;当包含myString(s) 的类型被验证时,该列表的元素也将被验证,@NotNull 约束将应用于每个元素。
    【解决方案4】:

    Bean 验证 2.0/Hibernate 验证器 6.0

    Bean Validation 2.0(其中 Hibernate Validator 6.0 是参考实现)允许直接在泛型类型参数上使用其验证注释。这在Hibernate 6.0 release documentation 中注明:

    Hibernate Validator 6.0 是 Bean Validation 2.0 规范的参考实现,因此它具有所有新功能:

    • 对容器元素约束和级联验证的一流支持(想想private Map&lt;@Valid @NotNull OrderCategory, List&lt;@Valid @NotNull Order&gt;&gt; orderByCategories;);

    如果项目使用 Java 8 和 Bean Validation 2.0,则可以使用此功能来验证列表中的每个元素:

    private List<@NotNull String> myString; // Validate that none of the list items is null
    

    Bean 验证 1.2/Hibernate 验证器 5.2

    Hibernate 5.2(带有 Bean Validation 1.2)添加了该功能的受限版本,以允许直接在泛型类型参数上进行验证注释。但是,它的内置 Bean Validation 或 Hibernate Validation 约束都不能以这种方式使用,因为由于向后兼容的原因,注释没有指定 ElementType.TYPE_USE。此外,可以为映射值而不是映射键指定类型参数约束。这在Hibernate Validator 5.2 documentation中都有描述:

    从 Java 8 开始,可以直接在参数化类型的类型实参上指定约束。但是,这需要在约束定义中通过@Target 指定ElementType.TYPE_USE。为了保持向后兼容性,内置 Bean Validation 以及 Hibernate Validator 特定约束尚未指定 ElementType.TYPE_USE

    [...]

    当对 Iterable 类型参数应用约束时,Hibernate Validator 将验证每个元素。

    [...]

    类型参数约束也会针对映射值进行验证。忽略键上的约束。

    总结

    总而言之,如果代码使用 Java 8 和 Bean Validation 2.0(例如 Hibernate Validator 6),则可以对泛型列表和映射类型参数进行注解:

    private List<@NotNull String> myString;
    

    如果代码使用带有 Bean Validation 1.2 和 Hibernate Validator 5.2 的 Java 8,则可以在其定义中使用 TYPE_USE 编写自定义验证注释,并将其应用于集合或映射值的泛型类型:

    private List<@MyCustomNotNull String> myString;
    

    如果代码未使用 Java 8 或在 5.2 之前的 Hibernate Validator 版本上,则可以编写自定义约束来验证集合或映射的每个元素并将其应用于集合或映射本身。

    @MyCustomNotNullElements
    private List<String> myString;
    

    【讨论】:

      猜你喜欢
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      • 2013-11-23
      • 2012-05-12
      • 2011-07-24
      相关资源
      最近更新 更多