繁体   English   中英

Spring MVC在Tomcat 6.0.35上使用@RequestParam和RequestMethod.DELETE

[英]Spring MVC using @RequestParam with RequestMethod.DELETE on Tomcat 6.0.35

我有一个简单的方法(在Tomcat 6.0.35上运行),如下所示:

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

当我发送一个DELETE请求,其中包含类似参数的帖子(d = gggg在正文中),我得到400 Bad Request。 但如果我把它改成

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

它完美地运作。 我正在使用Firefox附加组件来测试它(以及python和Spring的RestTemplate,结果相同)这里的请求是如何看待POST的(a是一个带有参数a的cope粘贴方法):

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的参数,这意味着即使RFC 不限制此类使用 ,Tomcat也会主动限制此用例(虽然它确实说某些现有实现可能会拒绝此类请求,但Tomcat只会抛出它的参数远)。 是什么让一个人使用Spring和Tomcat并尝试将带有参数的DELETE请求发送给丑陋的解决方案,例如使用@RequestBody获取所有请求体并手动提取它,这使得您想要删除某些地图的某些地方的无辜方法包含请求正文。

@fmucar

我遇到了类似的问题,我发现的解决方案是在查询字符串中添加字段。 我仍然想知道以这种方式排除表单正文的原因,但是现在这是一个解决方法。

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

我正在使用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.Connector中找到了parseBodyMethods,这里是Tomcat的文档:

这在希望支持PUT请求的POST样式语义的RESTful应用程序中很有用。 请注意,除POST之外的任何设置都会导致Tomcat的行为方式违反servlet规范的意图。 这里根据HTTP规范明确禁止HTTP方法TRACE。 默认为POST( 来源

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM