【问题标题】:Why isn't the Spring DispatcherServlet finding my controller method?为什么 Spring DispatcherServlet 找不到我的控制器方法?
【发布时间】:2016-04-28 13:50:29
【问题描述】:

假设我有以下 Spring 控制器:

@Controller
public class FooController
{
    @RequestMapping(value = "/foo", method = RequestMethod.GET, headers = { "Content-Type=text/plain" })
    @ResponseBody
    public String foo(String bar)
    {
        return "Bar is " + bar;
    }
}

这是相关的 web.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     id="WebApp_ID"
     version="2.5">
  <display-name>Foo</display-name>
  <servlet>
    <servlet-name>FooServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/servlet.xml</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>FooServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

这里是相关的 servlet.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
  <mvc:annotation-driven/>
  <bean id="FooController" class="foo.FooController"/>
</beans>

仅供参考,我使用的是 Spring Framework 3.0.5 版。我知道这是一个旧版本,但这是我必须克服的限制。

所以我将从上面构建的 WAR 文件(例如 FooApp.war)部署到 Tomcat(版本 7.0.67)。一切开始正常。但是当我导航到 http://localhost:8080/FooApp/foo?bar=baz 时,我在浏览器中收到 404 错误,在 Tomcat 控制台中出现以下错误:

Apr 28, 2016 9:43:33 AM org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver handleNoSuchRequestHandlingMethod
WARNING: No matching handler method found for servlet request: path '/foo', method 'GET', parameters map['bar' -> array<String>['baz']]

所以我的问题是,我在配置中做错了什么导致了这个问题?我确定它是某种东西,但我无法弄清楚它是什么。

编辑:根据 M. Deinum 的评论删除了 SimpleUrlHandlerMapping

【问题讨论】:

  • 您能在启动日志中看到正在创建的映射吗?如果创建了映射,肯定会在那里提及。您也正在使用注释,所以为什么不将 component:scan 添加到您的 servlet 配置中,您不需要手动进行 url-handler 映射。这在 Spring 3 中得到支持
  • 删除SimpleUrlHandlerMapping
  • @M.Deinum 谢谢,我删除了它,但我仍然遇到问题。我猜SimpleUrlHandlerMapping 是多余的吗?
  • @VineetKasat 是的,我可以看到正在创建的映射:Apr 28, 2016 9:58:15 AM org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler INFO: Mapped URL path [/foo] onto handler 'FooController' Apr 28, 2016 9:58:15 AM org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler INFO: Mapped URL path [/foo.*] onto handler 'FooController' Apr 28, 2016 9:58:15 AM org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler INFO: Mapped URL path [/foo/] onto handler 'FooController'
  • 不,它不是,但它服务于一个完全不同的目的。还要删除headers,因为您可能不是请求文本而是HTML。

标签: java spring web-services spring-mvc tomcat


【解决方案1】:

我从here 下载了示例项目,并开始查看它与我的测试项目之间的不同之处。我最终将其缩小到在我的控制器方法中的@RequestMapping 注释中存在headers = { "Content-Type=text/plain" }。删除后,一切正常。

【讨论】:

    【解决方案2】:

    在 servlet.xml 中添加“context:component-scan base-package="package name" /”。这将启用控制器的自动扫描。

    【讨论】:

    • 是的,我知道这一点,但我想了解我在手动设置控制器时做错了什么。简单地把它留给 Spring Framework 的“自动”并没有给我更多的洞察力。
    • 你在做什么手动设置控制器。查看何时在 servlet.xml 中仅定义 bean。您的控制器仅注册为 bean。没有控制器属性。好的,在您的 xml 中添加“context:annotation-config”。它会告诉 spring 将 Controller 作为请求处理程序 bean,然后将其注册为控制器。
    • 在 servlet.xml 中定义“context:annotation-config”后,@Controller 注释将起作用,因为它将指示 spring 搜索此注释并将其注册为处理程序。我认为这会对你有所帮助
    • 据我了解,mvc:annotation-driven 本质上与context:annotation-config 做同样的事情,只是为 Spring MVC 而不是一般指定。但也许我使用的 Spring Framework 版本太旧了。
    • 我尝试用context:annotation-config 替换mvc:annotation-driven,但没有解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 2017-12-16
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    相关资源
    最近更新 更多