2012-06-12 28 views
8

我有一個簡單的方法,看起來像這樣(在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請求發送一個類似於後類型的數組,但似乎更基本的東西是錯誤的。

回答

13

在完成一些研究和調試後,我發現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

0

我有一個類似的問題,我發現是添加字段的查詢字符串的分辨率。我仍然想知道爲什麼要以這種方式排除一個表格主體的原因,但現在這是一個解決方法。

因此,對於您的示例,這意味着將主機:~~~~~:8080 URL添加爲 ?a = asdas 。

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

0

這是一個很老的帖子,但如果其他人正在尋找如何在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