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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25375046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:01:16  来源:igfitidea点击:

Passing data in the body of a DELETE request

springspring-mvc

提问by Alex

I have two Spring MVC controller methods. Both receive the same data in the request body (in the format of an HTLM POSTform: version=3&name=product1&id=2), but one method handles PUTrequests and another DELETE:

我有两个 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) {

//...
}

In the first method, all fields of the productargument are correctly initialised. In the second, only the idfield is initialised. Other fields are nullor 0. (idis, probably, initialised because of the idpath variable).

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

I can see that the HttpServletRequestobject contains values for all fields in the request body (version=3&name=product1&id=2). They just are not mapped to the fields of the productparameter.

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

How can I make the second method work?

我怎样才能使第二种方法起作用?

I also tried to use the @RequestParamannotated parameters. In the method that handles PUTrequests, it works. In the DELETEmethod, I get an exception: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'version' is not present.

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

I need to pass data in the body of DELETErequests because the data contain a row version which is used for optimistic locking.

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

回答by geoand

The problem is not a Springproblem, but a Tomcatproblem.

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

By default, Tomcat will only parse arguments that are in the form style, when the HTTP method is POST(at least for version 7.0.54 that I checked but it's probably the same for all Tomcat 7 versions).

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

In order to be able to handle DELETE methods as well you need to set the parseBodyMethodsattribute of the Tomcat Connector. The connector configuration is done in server.xml.

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

Your updated connector would most likely look like:

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

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

Hereis documentation page for configuring Tomcat connectors.

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

Once you setup Tomcat to parse the parameters, Spring will work just fine (although in your case you will probably need to remove @RequestBodyfrom the controller method)

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

回答by coder

You can try adding the annotation @RequestBody to your Product argument.

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

But if you just need to pass version information, using a request param is more appropriate.

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

So add a new argument in your delete method @RequestParam("version") int version, and when calling the delete method pass a query param like ..ajax/products/123?version=1

因此,在您的删除方法 @RequestParam("version") int version 中添加一个新参数,并在调用 delete 方法时传递一个查询参数,例如 ..ajax/products/123?version=1

As you said request param is not working for you in delete, can you post the exact url you used and the method signature ?

正如您所说的请求参数在删除时对您不起作用,您能否发布您使用的确切网址和方法签名?

回答by GreatC

Spring boot 1.5.*

弹簧靴 1.5.*

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

回答by KESHAV KUMAR

Passing data in the body of a DELETE request

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

@Component public class CustomiseTomcat implements WebServerFactoryCustomizer {

@Component 公共类 CustomiseTomcat 实现了 WebServerFactoryCustomizer {

@Override
public void customize(TomcatServletWebServerFactory factory) {

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

}

}