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

时间:2014-08-19 02:56:15

标签: spring spring-mvc

我有两个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个请求的主体中传递数据,因为数据包含用于乐观锁定的行版本。

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

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

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

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

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

答案 2 :(得分:1)

Spring boot 1.5。*

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

答案 3 :(得分:1)

对于Spring Boot 2.0 +:

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

答案 4 :(得分: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");
        }
    });
}

}