Spring MVC - @Valid 在 REST 服务中的 bean 列表中 [英] Spring MVC - @Valid on list of beans in REST service

查看:25
本文介绍了Spring MVC - @Valid 在 REST 服务中的 bean 列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Spring MVC REST 服务 (json) 中,我有一个这样的控制器方法:

In a Spring MVC REST service (json), I have a controller method like this one :

@RequestMapping(method = RequestMethod.POST, value = { "/doesntmatter" })
@ResponseBody
public List<...> myMethod(@Valid @RequestBody List<MyBean> request, BindingResult bindingResult) {

其中 MyBean 类具有 bean 验证注释.

Where the MyBean class has bean validation annotations.

在这种情况下似乎没有进行验证,尽管它适用于其他控制器.

The validations don't seem to take place in this case, although it works well for other controllers.

我不想将列表封装在一个 dto 中,这会改变 json 输入.

I don't want to encapsulate the list in a dto this that would change the json input.

为什么没有对 bean 列表的验证?有哪些替代方案?

Why is there no validations for a list of beans ? What are the alternatives ?

推荐答案

@Valid 是一个 JSR-303 注释,JSR-303 适用于 JavaBeans 上的验证.java.util.List 不是 JavaBean(根据 JavaBean 的官方描述),因此它不能直接使用符合 JSR-303 的验证器进行验证.这得到了两个观察结果的支持.

@Valid is a JSR-303 annotation and JSR-303 applies to validation on JavaBeans. A java.util.List is not a JavaBean (according to the official description of a JavaBean), hence it cannot be validated directly using a JSR-303 compliant validator. This is supported by two observations.

JSR-303 规范3.1.3部分说:

除了支持实例验证,还支持对象图的验证.图验证的结果作为一组统一的约束违规返回.考虑 bean X 包含 Y 类型字段 的情况.通过使用@Valid 注释来注释字段Y,验证器将在验证X 时验证Y(及其属性).包含在声明为类型 Y(子类、实现)的字段中的值的确切类型 Z 是在运行时确定的.使用 Z 的约束定义.这确保了标记为 @Valid 的关联的正确多态行为.

In addition to supporting instance validation, validation of graphs of object is also supported. The result of a graph validation is returned as a unified set of constraint violations. Consider the situation where bean X contains a field of type Y. By annotating field Y with the @Valid annotation, the Validator will validate Y (and its properties) when X is validated. The exact type Z of the value contained in the field declared of type Y (subclass, implementation) is determined at runtime. The constraint definitions of Z are used. This ensures proper polymorphic behavior for associations marked @Valid.

集合值、数组值和通常可迭代字段和属性也可以用@Valid 注释进行修饰.这会导致迭代器的内容被验证.支持任何实现 java.lang.Iterable 的对象.

Collection-valued, array-valued and generally Iterable fields and properties may also be decorated with the @Valid annotation. This causes the contents of the iterator to be validated. Any object implementing java.lang.Iterable is supported.

我用粗体标记了重要的信息.本节暗示,为了验证集合类型,必须将其封装在bean 中(由考虑bean X 包含Y 类型字段的情况);此外,集合不能直接验证(Collection-valued、array-valued 和通常可迭代的字段和属性也可以装饰,重点是字段和属性).

I have marked the important pieces of information in bold. This section implies that in order for a collection type to be validated, it must be encapsulated inside a bean (implied by Consider the situation where bean X contains a field of type Y); and further that collections cannot be validated directly (implied by Collection-valued, array-valued and generally Iterable fields and properties may also be decorated, with emphasis on fields and properties).

实际的 JSR-303 实现

Actual JSR-303 implementations

我有一个示例应用程序来测试集合使用 Hibernate Validator 和 Apache Beans Validator 进行验证.如果你在这个示例上运行测试作为 mvn clean test -Phibernate(使用 Hibernate Validator)和 mvn clean test -Papache(用于 Beans Validator),两者都拒绝直接验证集合,这似乎符合规范.由于 Hibernate Validator 是 JSR-303 的参考实现,此示例进一步证明了集合需要封装在 bean 中才能进行验证.

I have a sample application that tests collection validation with both Hibernate Validator and Apache Beans Validator. If you run tests on this sample as mvn clean test -Phibernate (with Hibernate Validator) and mvn clean test -Papache (for Beans Validator), both refuse to validate collections directly, which seems to be in line with the specification. Since Hibernate Validator is the reference implementation for JSR-303, this sample is further proof that collections need to be encapsulated in a bean in order to be validated.

清除后,我会说尝试以问题中所示的方式直接将集合传递给控制器​​方法也存在设计问题.即使验证直接在集合上工作,控制器方法也无法使用替代数据表示,例如自定义 XML、SOAP、ATOM、EDI、Google Protocol Buffers 等,它们不直接映射到集合.为了支持这些表示,控制器必须接受并返回对象实例.这需要以任何方式将集合封装在对象实例中.因此,强烈建议按照其他答案的建议将 List 包装在另一个对象中.

With that cleared, I would say that there is also a design problem in trying to pass a collection to a controller method directly in the way shown in the question. Even if validations were to work on the collections directly, the controller method will be unable to work with alternate data representations such as custom XML, SOAP, ATOM, EDI, Google Protocol Buffers etc. which do not map directly to collections. For supporting those representations, the controller must accept and return object instances. That would require encapsulating the collection inside an object instance any way. It would therefore be highly advisable to wrap the List inside another object as other answers have suggested.

这篇关于Spring MVC - @Valid 在 REST 服务中的 bean 列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆