Spring MVC带注释的控制器方法,无法“查找”DELETE操作的方法

时间:2012-03-23 13:03:29

标签: spring http rest servlets spring-mvc

以下是实际代码:

@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!";
}

向/ compet / 200发送DELETE请求会导致错误:

“HTTP状态405 - 不支持请求方法'DELETE'”

来自Spring的日志记录确认无法找到此方法的路径:

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

我的回答是“BUH?”。

5 个答案:

答案 0 :(得分:4)

我有同样的问题。有什么帮助,它可能不是最终解决方案,但对我有用:

更改方法 deleteCompetitors 的注释和参数。删除id(方法参数也是如此)。从HttpServletRequest中读取 id 参数。

@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!";
}

id参数以这种方式通过标头传递(客户端的代码 - 未完成):

DefaultHttpClient httpClient = new DefaultHttpClient();

HttpDelete httpDelete = new HttpDelete...

...

httpDelete.setHeader("id", "123");

...

httpClient.execute(httpDelete);

我正在使用Apache HttpClient。

答案 1 :(得分:1)

普通浏览器仅支持get / post。

Spring通过使用隐藏参数解决了这个问题,启用它,在下面添加到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>

答案 2 :(得分:0)

尝试将其更改为method = RequestMethod.GET并查看其是否有效。

答案 3 :(得分:0)

你试过这个http://www.codereye.com/2010/12/configure-tomcat-to-accept-http-put.html吗?这只会在您运行Tomcat时运行。似乎大多数应用服务器已禁用处理PUT和DELETE请求的能力是默认的。

当然,启用此功能可能会让您遇到新的安全漏洞。

答案 4 :(得分:0)

我最近遇到了这个问题。以下是我的一些调查结果/评论:

我使用Spring 3.2.2运行tomcat 7.0.42

在所有这些情况下,以下消息都会在日志中吐出。 405 Not Methoded方法返回给客户端。

org.springframework.web.servlet.PageNotFound  - Request method 'DELETE' not supported
  1. 您使用的REST URL错误。即使端点不在那里,你仍然可以获得405。
  2. 您尚未登录,无权执行任何操作,更不用说DELETE
  3. 实际上不支持DELETE,因为没有使用method = RequestMethod.GET
  4. 的函数
  5. 由于readonly init-param设置为true,Tomcat阻止DELETE,PUT等操作
  6. 该方法存在,允许DELETE,一切都很好,除非方法中有未捕获的运行时异常(例如Null指针异常)
  7. 除了3和4之外,显示的消息和响应非常具有误导性。它让你失去调查兔子洞,最终没有结果。

    最终成为我的问题的是我们有这样的方法:

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

    它应该是这样的:

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

    看到区别?它是@RequestParam之后的缺失(“objectName”)。它在STS中编译并运行良好,但是当直接部署在tomcat服务器上时,它不起作用。

    感谢@fmelan上面的帖子,因为它帮助我们找到了这个小错字。

    这看起来不像是你的问题,但是对于其他任何一个试图弄清楚为什么不支持“DELETE”的人... ...