11

Here is the actual code:

@RequestMapping(value = "/competitors/{id}", method = RequestMethod.GET) public Competitor getCompetitor(@PathVariable("id") long id) { Competitor competitor = competitorService.getCompetitorById(id); if (null == competitor) { EmptyResultDataAccessException e = new EmptyResultDataAccessException(1); logger.log(Level.WARN, e.getMessage()); throw e; } return competitor; } @RequestMapping(value = "/competitors/{id}", method = RequestMethod.DELETE) public String deleteCompetitor(@PathVariable("id") long id) { Competitor competitor = new Competitor(); competitor.setId(id); competitorService.deleteCompetitor(competitor); return "Solid gone!"; } 

Sending a DELETE request to /competitors/200 results in the error:

"HTTP Status 405 - Request method 'DELETE' not supported"

The logging from Spring confirms that no route to this method can be found:

5559 [tomcat-http--3] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcher' processing DELETE request for [/vrsboserver/competitors/200] 5562 [tomcat-http--3] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Matching patterns for request [/competitors/200] are [/competitors/{id}] 5565 [tomcat-http--3] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapping [/competitors/200] to handler 'com.gtspt.vrsboserver.controllers.CompetitorController@4fe7f80' 5565 [tomcat-http--3] DEBUG org.springframework.web.servlet.mvc.WebContentInterceptor - Looking up cache seconds for [/competitors/200] 5565 [tomcat-http--3] DEBUG org.springframework.web.servlet.mvc.WebContentInterceptor - Applying default cache seconds to [/competitors/200] 5566 [tomcat-http--3] DEBUG org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [com.gtspt.vrsboserver.controllers.CompetitorController@4fe7f80]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'DELETE' not supported 5567 [tomcat-http--3] DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [com.gtspt.vrsboserver.controllers.CompetitorController@4fe7f80]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'DELETE' not supported 5568 [tomcat-http--3] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [com.gtspt.vrsboserver.controllers.CompetitorController@4fe7f80]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'DELETE' not supported 5568 [tomcat-http--3] WARN org.springframework.web.servlet.PageNotFound - Request method 'DELETE' not supported 

To which my response is "BUH?".

5
  • Are all of your Spring jars the same version? Commented Mar 23, 2012 at 13:14
  • Just to be sure, you have verified that a GET works on the same mapping? Commented Mar 23, 2012 at 13:19
  • GET definitely works. Maven is getting my Spring jars, using "${org.springframework.version}" as every version field, so they're definitely all matching. Commented Mar 23, 2012 at 13:20
  • Based on this info, I'm stumped. Please be sure to check your effective pom as you may be pulling in a transitive Spring dep without utilizing your version property. If I worked with you, I would be asking you to push this so I can debug. Commented Mar 23, 2012 at 13:37
  • Upgrading from Spring 3.0.0 to Spring 3.1.0 has magically fixed this. Commented Mar 23, 2012 at 13:57

5 Answers 5

4

I had same problem. What helps and it's probably not the final solution but is working for me:

Change of annotations and parameters of the method deleteCompetitors. Remove id (method parameter too). Read the id parameter from HttpServletRequest.

@RequestMapping(value = "/competitors", method = RequestMethod.DELETE) public String deleteCompetitor(HttpServletRequest request) { String idHeader = request.getHeader("id"); Integer id = Integer.valueOf(idHeader).intValue(); Competitor competitor = new Competitor(); competitor.setId(id); competitorService.deleteCompetitor(competitor); return "Solid gone!"; } 

The id parameter is passed by header this way (code of the client - not complete):

DefaultHttpClient httpClient = new DefaultHttpClient(); HttpDelete httpDelete = new HttpDelete... ... httpDelete.setHeader("id", "123"); ... httpClient.execute(httpDelete); 

I'm using the Apache HttpClient.

Sign up to request clarification or add additional context in comments.

Comments

1

Normal browser only support get / post.

Spring resolved this by using a hidden parameter, to enable it, add below to your web.xml:

<filter> <filter-name>httpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>httpMethodFilter</filter-name> <servlet-name>springDispatcher</servlet-name> </filter-mapping> 

Comments

0

Try changing it to method = RequestMethod.GET and see if it works.

5 Comments

A method with the signature for GET already exists (see the code posted), and works.
How are you telling the browser to make a DELETE request? Where is that header set? Like in this link: ibm.com/developerworks/webservices/library/wa-restful/…
Do you use method=DELETE in your form? I'm curious, because I honestly don't know.
Yes, how are you testing ? You can use this Google Extension to test REST requests : chrome.google.com/webstore/detail/…
I'm using this addon for Firefox: addons.mozilla.org/en-US/firefox/addon/restclient - the request type is definitely being set properly in the header.
0

Did you try this http://www.codereye.com/2010/12/configure-tomcat-to-accept-http-put.html? This will only work of course of you are running on Tomcat. It seems that most app servers have disabled the ability to handle PUT and DELETE request be default.

Of course, enabling this will probably expose you to new security holes.

Comments

0

I ran into this problem recently. Here are a couple of my findings/comments:

I am running tomcat 7.0.42 with Spring 3.2.2

The following message is spit out on the log in all of these cases. 405 Method Not Allowed is returned to the client.

org.springframework.web.servlet.PageNotFound - Request method 'DELETE' not supported 
  1. The REST URL you are using is wrong. Even though the endpoint isn't there, you still get a 405.
  2. You are not logged in and are not authorized to perform any action, let alone a DELETE
  3. DELETE actually isn't supported because there is no function with method = RequestMethod.GET
  4. Tomcat is blocking operations like DELETE, PUT, etc. due to the readonly init-param set to true
  5. The method is present, DELETE is allowed, everything is fine except there was an uncaught runtime exception (e.g. Null Pointer Exception) in the method

With the exception of 3 and 4, the message shown and the response is very misleading. It sends you down investigation rabbit holes that end up fruitless.

What ended up being my problem is that we had a method like this:

public void deleteSomething(HttpServletRequest request, HttpServletResponse response, @PathVariable("id") long id, @RequestParam String objectName); 

It SHOULD be this:

public void deleteSomething(HttpServletRequest request, HttpServletResponse response, @PathVariable("id") long id, @RequestParam("objectName") String objectName); 

See the difference? It is the missing ("objectName") after @RequestParam. It compiles and runs fine in STS, but when deployed on a tomcat server directly, it doesn't work.

Thanks to @fmelan for the post above because it helped us find this small typo.

This doesn't look like it was your problem, but for anyone else who is stuck trying to figure out why 'DELETE' is not supported ...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.