Spring MVC的Tomcat上使用@RequestParam与RequestMethod.DELETE 6.0.35

问题描述:

我有一个简单的方法,看起来像这样(在Tomcat 6.0.35上运行)像参数(在体内d = gggg)我得到一个400错误的请求。 但是,如果我将其更改为Spring MVC的Tomcat上使用@RequestParam与RequestMethod.DELETE 6.0.35

@RequestMapping(value = "/bla/d", method = RequestMethod.POST) 
@ResponseStatus(HttpStatus.NO_CONTENT) 
public void d(@RequestParam String d){ 
    //logic here 
} 

它完美地工作。 我使用的是Firefox插件来测试它(和Python和Spring的RestTemplate具有相同的结果),这里是如何要求的外观与POST(一个被命名为应付粘贴方法与参数):

POST /bla/a HTTP/1.1 
Host: ~~~~:8080 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Content-Length: 7 
Pragma: no-cache 
Cache-Control: no-cache 
a=asdas 

HTTP/1.1 204 No Content 
Server: Apache-Coyote/1.1 
Date: Tue, 12 Jun 2012 09:29:46 GMT 

删除看起来像:

DELETE /bla/d HTTP/1.1 
Host: ~~~~~:8080 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Content-Length: 7 
d=asdas 

HTTP/1.1 400 Bad Request 
Server: Apache-Coyote/1.1 
Content-Type: text/html;charset=utf-8 
Content-Length: 971 
Date: Tue, 12 Jun 2012 09:30:04 GMT 
Connection: close 

请帮助我,我可能会错过一些愚蠢的东西,但我只是不能看到它。 我最初的问题是通过DELETE请求发送一个类似于后类型的数组,但似乎更基本的东西是错误的。

在完成一些研究和调试后,我发现Spring的ServletWebREquest调用了org.apache.catalina.connector.RequestFacade.getParameterValues的getParameterValues,它调用了getParameterValues,其中我找到了以下行(Request.java 2599 -2600):

if (!getMethod().equalsIgnoreCase("POST")) 
return; 

杀死任何企图用DELETE发送POST样的参数,这意味着Tomcat是积极地限制了该用例,即使RFC does not restrict such usage(虽然它说,一些现有的实现可能会拒绝这样的请求,Tomcat只是抛出它的参数)。 什么带来了一个使用Spring和Tomcat,并试图发送带有参数的DELETE请求到丑陋的解决方案,如使用@RequestBody获取所有请求主体并手动提取它,这使得你想要的无辜方法只是想删除某些意识到某些包含请求正文的地图。

@fmucar

我有一个类似的问题,我发现是添加字段的查询字符串的分辨率。我仍然想知道为什么要以这种方式排除一个表格主体的原因,但现在这是一个解决方法。

因此,对于您的示例,这意味着将主机:~~~~~:8080 URL添加为 ?a = asdas 。

我使用的是spring-webmvc:3.2.4.RELEASE,所以我不确定这是否会在你的版本中起作用。

这是一个很老的帖子,但如果其他人正在寻找如何在DELETE方法上启用@RequestParam,这就是我在tomcat 8.5.4上所做的。

@Value("${server.parseBodyMethods}") 
private String parseBodyMethods; 

@Bean 
public TomcatEmbeddedServletContainerFactory containerFactory() { 
    return new TomcatEmbeddedServletContainerFactory() { 
     protected void customizeConnector(Connector connector) { 
      super.customizeConnector(connector); 
      connector.setParseBodyMethods(parseBodyMethods); 
     } 
    }; 
} 

插入'POST,DELETE'到该定制器,并且您的删除请求参数应该开始工作。

我在org.apache.catalina.connector中找到了parseBodyMethods。连接器,这里是Tomcat的文档:

这对于希望支持PUT请求的POST风格语义的REST风格的应用程序很有用。请注意,除POST之外的任何设置都会导致Tomcat的行为违背servlet规范的意图。根据HTTP规范,此处特别禁止HTTP方法TRACE。默认为POST(Source