【问题标题】:JSR 303: How to Validate a Collection of annotated objects?JSR 303:如何验证带注释对象的集合?
【发布时间】:2011-05-05 15:22:25
【问题描述】:

是否可以在 JSR 303 - Jave Bean Validation 中验证集合本身没有任何注释但其中包含的元素的对象集合?

例如,这是否可能由于第二个人的空名称而导致违反约束:

List<Person> people = new ArrayList<Person>();
people.add(new Person("dave"));
people.add(new Person(null));

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<List<Person>>> validation = validator.validate(people);

【问题讨论】:

    标签: java bean-validation hibernate-validator jsr


    【解决方案1】:

    您当然也可以只遍历列表并在每个元素上调用 Validator.validate。或者将 List 放入一些包装 bean 并使用 @Valid 对其进行注释。扩展 ArrayList 以进行验证对我来说似乎是错误的。 您是否有想要解决此问题的特定用例?如果是这样,也许您可​​以再解释一下。回答您最初的问题:

    是否可以验证 JSR 303 中的对象集合 - Jave Bean 验证在哪里 集合本身没有任何 注释但包含的元素 在做什么?

    没有

    【讨论】:

    • 我正在使用 JAX-RS 并有一个 json 对象列表,我将其解析为 Java bean 列表。我没有列表的包装器对象,所以没有要注释的属性...我认为如果这将是没有包装 bean 的一般问题,而不是为每种类型的列表创建一个新的包装器仅注释通用列表子类可能更容易。我认为这也是可以实现的,尽管按照您的建议使用通用包装 bean,例如: public class ValidatableListBean> { @Valid private T list; }
    • 其实,这个类可能看起来更像这样: public class ValidatableBeanList { @Valid private List list; }
    • ValidatableBeanList 对您的用例来说似乎是合理的。
    • 在 JSR 380 中是否发生了变化?
    【解决方案2】:

    是的,只需将@Valid 添加到集合中即可。

    这里是来自 Hibernate 验证器参考的an example

    public class Car {
      @NotNull
      @Valid
      private List<Person> passengers = new ArrayList<Person>();
    }
    

    这是标准的 JSR-303 行为。请参阅spec 的第 3.1.3 节。

    【讨论】:

    【解决方案3】:

    您也可以将@NotEmpty 添加到收藏夹中。

    public class Car {
      @NotEmpty(message="At least one passenger is required")
      @Valid
      private List<Person> passengers = new ArrayList<Person>();
    }
    

    这将确保至少有一名乘客在场,@Valid 注释确保每个 Person 对象都经过验证

    【讨论】:

      【解决方案4】:

      我写了这个通用类:

      public class ValidListWrapper<T> {
      
          @Valid
          private List<T> list;
      
          public ValidListWrapper(List<T> list) {
              this.list = list;
          }
      
          public List<T> getList() {
              return list;
          }
      
      }
      

      如果您使用 Jackson 库反序列化 JSON,您可以在构造函数上添加 @JsonCreator 注释,Jackson 会自动将 JSON 数组反序列化为包装对象。

      【讨论】:

      • 你能否为 List 编写一个自定义验证器,通过这些对象的某些属性检查是否存在重复对象?就像...如果多个对象在属性“名称”处具有相同的值
      【解决方案5】:

      从 Bean Validator 2.0 开始,这两种方法都有效:

      class MyDto {
      
          private List<@Valid MyBean> beans;
      }
      

      class MyDto {
      
          @Valid
          private List<MyBean> beans;
      }
      

      【讨论】:

      • 有什么区别或者至少是推荐的方式吗?我在休眠验证器文档中找不到它,看起来他们文档中的示例使用第一种方法
      • @Whimusical — 我认为与@Valid 没有区别。 Java 8 中引入了泛型类型参数的注解,并且较旧的 Bean Validation 1.2 注解没有设置为附加到泛型类型参数。这在 Bean Validation 2.0/Hibernate 6 中发生了变化(在 Hibernate 5.2 中也有所改变)。我怀疑对于较新的代码,将@Valid 放在注释本身中更为惯用,因为它在概念上适用于集合的每个元素。我在这里更详细地讨论这个:stackoverflow.com/a/33481403/1108305.
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 2012-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-10
      • 2011-09-12
      相关资源
      最近更新 更多