在 Spring MVC REST 服务(json)中,我有一个像这样的控制器方法:
@RequestMapping(method = RequestMethod.POST, value = { "/doesntmatter" })
@ResponseBody
public List<...> myMethod(@Valid @RequestBody List<MyBean> request, BindingResult bindingResult) {
其中 MyBean 类具有 bean 验证注释。
在这种情况下,验证似乎没有发生,尽管它对于其他控制器来说效果很好。
我不想将列表封装在 dto 中,这会更改 json 输入。
为什么没有对 bean 列表进行验证?有哪些替代方案?
@Valid
是 JSR-303 注释,JSR-303 适用于 JavaBean 上的验证。 Ajava.util.List
不是 JavaBean(根据官方说明 https://docs.oracle.com/javaee/5/tutorial/doc/bnair.htmlJavaBean 的),因此不能直接使用符合 JSR-303 的验证器进行验证。这得到了两个观察结果的支持。
Section 3.1.3 of the JSR-303规格 https://beanvalidation.org/1.0/spec/#d0e991说:
除了支持实例验证之外,还支持对象图的验证。图验证的结果作为一组统一的约束违规返回。考虑以下情况:bean X 包含类型 Y 的字段. By 使用@Valid注释来注释字段Y, 验证器当 X 被验证时将验证 Y(及其属性)。类型 Y(子类、实现)声明的字段中包含的值的确切类型 Z 在运行时确定。使用 Z 的约束定义。这确保了标记为 @Valid 的关联具有正确的多态行为。
集合值、数组值和一般来说可迭代字段和属性也可以使用 @Valid 注释进行修饰。这会导致迭代器的内容得到验证。支持任何实现 java.lang.Iterable 的对象。
我已将重要的信息用粗体标出。本节暗示为了验证集合类型,必须将其封装在 bean 内(由Consider the situation where bean X contains a field of type Y
);此外,集合不能直接验证(暗示Collection-valued, array-valued and generally Iterable fields and properties may also be decorated
,重点是字段和属性).
实际的 JSR-303 实现
I have 示例应用程序 https://github.com/manish-in-java/stackoverflow-questions/tree/master/17207766使用 Hibernate Validator 和 Apache Beans Validator 测试集合验证。如果您对此示例运行测试mvn clean test -Phibernate
(使用 Hibernate 验证器)和mvn clean test -Papache
(对于 Beans Validator),两者都拒绝直接验证集合,这似乎符合规范。由于 Hibernate Validator 是 JSR-303 的参考实现,因此该示例进一步证明集合需要封装在 bean 中才能进行验证。
清除了这一点后,我想说,尝试以问题中所示的方式直接将集合传递给控制器方法也存在设计问题。即使验证直接在集合上工作,控制器方法也无法使用不直接映射到集合的替代数据表示形式,例如自定义 XML、SOAP、ATOM、EDI、Google Protocol Buffers 等。为了支持这些表示,控制器必须接受并返回对象实例。这需要以任何方式将集合封装在对象实例内。因此,强烈建议将List
正如其他答案所建议的那样,在另一个对象内。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)