在DELETE请求的正文中传递数据

问题描述 投票:21回答:4

我有两个Spring MVC控制器方法。两者都在请求体中接收相同的数据(格式为HTLM POST形式:version=3&name=product1&id=2),但是一种方法处理PUT请求和另一种DELETE

@RequestMapping(value = "ajax/products/{id}", method = RequestMethod.PUT)
@ResponseBody
public MyResponse updateProduct(Product product, @PathVariable("id") int productId) {

//...
}

@RequestMapping(value = "ajax/products/{id}", method = RequestMethod.DELETE)
@ResponseBody
public MyResponse updateProduct(Product product, @PathVariable("id") int productId) {

//...
}

在第一种方法中,product参数的所有字段都已正确初始化。在第二个中,只有id字段被初始化。其他字段是null或0.(id可能由于id路径变量而初始化)。

我可以看到HttpServletRequest对象包含请求体(version=3&name=product1&id=2)中所有字段的值。它们只是没有映射到product参数的字段。

如何使第二种方法有效?

我也尝试使用@RequestParam注释参数。在处理PUT请求的方法中,它可以工作。在DELETE方法中,我得到一个例外:org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'version' is not present

我需要在DELETE请求的主体中传递数据,因为数据包含用于乐观锁定的行版本。

spring spring-mvc
4个回答
31
投票

问题不是Spring问题,而是Tomcat问题。

默认情况下,当HTTP方法为POST时,Tomcat将仅解析表单样式中的参数(至少对于我检查过的版本7.0.54,但对于所有Tomcat 7版本可能都是相同的)。

为了能够处理DELETE方法,您需要设置Tomcat连接器的parseBodyMethods属性。连接器配置在server.xml中完成。

您更新的连接器很可能如下所示:

<Connector port="8080" protocol="HTTP/1.1" 
           connectionTimeout="20000"
           redirectPort="8443"
           parseBodyMethods="POST,PUT,DELETE"
           URIEncoding="UTF-8" />

Here是用于配置Tomcat连接器的文档页面。

一旦你设置Tomcat来解析参数,Spring就可以正常工作(尽管在你的情况下你可能需要从控制器方法中删除@RequestBody


3
投票

您可以尝试将注释@RequestBody添加到Product参数中。

但是,如果您只需要传递版本信息,则使用请求参数更合适。

所以在你的删除方法@RequestParam(“version”)int版本中添加一个新参数,并在调用delete方法时传递一个像..ajax/products/123?version=1这样的查询参数

正如您所说,请求param在删除时不适合您,您可以发布您使用的确切网址和方法签名吗?


1
投票

春季靴子1.5。*

@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory(){
        @Override
        protected void customizeConnector(Connector connector) {
            super.customizeConnector(connector);
            connector.setParseBodyMethods("POST,PUT,DELETE");
        }
    };
}

0
投票

在DELETE请求的正文中传递数据

@Component公共类CustomiseTomcat实现WebServerFactoryCustomizer {

@Override
public void customize(TomcatServletWebServerFactory factory) {

    factory.addConnectorCustomizers( new TomcatConnectorCustomizer() {
        @Override
        public void customize(Connector connector) {
            connector.setParseBodyMethods("POST,PUT,DELETE");
        }
    });
}

}

© www.soinside.com 2019 - 2024. All rights reserved.