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

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

问题描述

在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.


3.1.3 部分/download.oracle.com/otn-pub/jcp/bean_validation-1.0-fr-oth-JSpec/bean_validation-1_0-final-spec.pdf?AuthParam=1456457081_36abb9cf126ac00192b03d69d2af0874\"rel =noreferrer> JSR-303规范说:

Section 3.1.3 of the JSR-303 Specification says that:

除支持实例验证外,还支持验证对象图。图验证的结果作为一组统一的约束违规返回。考虑 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 类型字段的情况) ;此外,集合无法直接验证(隐含的集合值,数组值和通常可迭代的字段和属性也可以装饰,重点是字段和属性)。

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协议缓冲区等,它们不直接映射到集合。为了支持这些表示,控制器必须接受并返回对象实例。这将需要以任何方式将集合封装在对象实例中。因此,强烈建议将 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 - REST服务中bean列表上的@Valid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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