当前位置: 首页 > 知识库问答 >
问题:

Spring MVC-@在REST服务中的bean列表上有效

段干茂实
2023-03-14

在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列表的验证?有哪些替代方案?

共有3个答案

白高逸
2023-03-14

尝试直接验证。类似于这样:

@Autowired
Validator validator;

@RequestMapping(method = RequestMethod.POST, value = { "/doesntmatter" })
@ResponseBody
public Object myMethod(@RequestBody List<Object> request, BindingResult bindingResult) {
    for (int i = 0; i < request.size(); i++) {
        Object o = request.get(i);
        BeanPropertyBindingResult errors = new BeanPropertyBindingResult(o, String.format("o[%d]", i));
        validator.validate(o, errors);
        if (errors.hasErrors())
            bindingResult.addAllErrors(errors);
    }
    if (bindingResult.hasErrors())
        ...
狄旻
2023-03-14

我能找到的唯一方法是包装列表,这也意味着JSON输入必须更改。

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

成为:

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

我们还需要:

import javax.validation.Valid;
import java.util.List;

public class MyBeanList {

    @Valid
    List<MyBean> list;

    //getters and setters....
}

这看起来也可以使用列表的自定义validatior,但我还没有做到这一点。

@Valid注释是标准JSR-303bean验证API的一部分,不是特定于Spring的构造。只要配置了适当的验证器,Spring MVC就会在绑定后验证@Valid对象。

参考:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html

杨雪松
2023-03-14

Valid是一个JSR-303注释,JSR-303适用于JavaBeans上的验证。A<代码>java。util。List不是JavaBean(根据JavaBean的官方描述),因此无法使用符合JSR-303的验证器直接验证它。这得到了两个观察结果的支持。

JSR-303规范第3.1.3节规定:

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

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

我已经用粗体标出了重要的信息。本节意味着为了验证集合类型,必须将其封装在bean中(考虑bean X包含类型为Y的字段的情况);此外,集合无法直接验证(由集合值、数组值和通常可Iterable字段和属性暗示,也可以修饰,重点是字段和属性)。

实际的JSR-303实现

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

清除了这个问题后,我想说尝试以问题中所示的方式将集合直接传递给控制器方法也存在设计问题。即使验证直接对集合起作用,控制器方法也将无法使用替代数据表示形式,例如自定义XML、SOAP、ATOM、EDI、Google协议缓冲区等。它们不直接映射到集合。为了支持这些表示,控制器必须接受并返回对象实例。这将需要以任何方式将集合封装在对象实例中。因此,正如其他答案所建议的那样,将List包装在另一个对象中是非常可取的。

 类似资料:
  • 问题内容: 在Spring MVC REST服务(json)中,我有一个像这样的控制器方法: MyBean类具有bean验证批注的位置。 尽管在其他控制器上效果很好,但似乎没有在这种情况下进行验证。 我不想将列表封装在dto中,这会改变json输入。 为什么没有对bean列表的验证?有哪些选择? 问题答案: 是JSR-303批注,JSR-303适用于JavaBeans上的验证。A 不是JavaBe

  • 我正在尝试使用以下命令从Ubuntu连接到副本集: Url如下所示: 我正在连接多个数据库,偶尔会看到以下错误: 和节点。js崩溃了。 我现在有点迷路了。主要的问题是它在MAC上运行得很好,我只在Ubuntu上看到这个问题。我正在使用node的最新mongo驱动程序。js 更新 我查看了本机驱动程序源代码: http://mongodb.github.io/node-mongodb-native/

  • 我使用CXF、REST服务和Apache Camel实现了以下API。 http://localhost:9090/api/compute http://localhost:9091/api/listaction null IllegalArgumentException:无效的URI:/API/ListAction/API/ListAction。如果您正在转发/桥接httpendpoint,则在

  • ` ` 在TOmCAT服务器中。我无法运行这个项目。? ` 严重:web应用程序[/SpringMvc4]中的Servlet[spring]抛出了load()异常Java。伊奥。FileNotFoundException:无法打开组织上的ServletContext资源[/WEB-INF/spring servlet.xml]。springframework。网状物上下文支持ServletCont

  • 我正在编写一个junit测试用例来测试rest调用。 我试图嘲笑售票服务,它工作正常,但当我在REST服务调用中嘲笑它时。它不嘲笑。 我正在使用springboot,mongodb与REST。 有什么解决这个问题的建议吗? }

  • 谢谢你的帮助!向你问好,安迪