Spring MVC - 使用注解将Controller映射到URL

5
我一直在遇到配置Spring Controller映射到特定URL的问题,我已经将它简化成了一个相当简单的场景,认为应该可以工作:
我使用注释来配置我的Controller类,代码如下:
@Controller
@RequestMapping(value = "/question/**")
public class QuestionController 
{

    /**
     * Method to build users questions list
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/list")
    public ModelAndView list(HttpServletRequest request, HttpServletResponse response) throws Exception{
        //Display Questions List
    }
}

控制器不需要进一步配置,我只需在我的webmvc配置中添加和..配置,这样控制器就会自动检测到。
现在,当我导航到/question/list时,应用程序无法找到资源,我收到一个ResourceNotFound错误。然而,如果我导航到/question/question/list,那么应用程序将正确加载我期望的页面。
有什么想法为什么会使用/question/question/list方法进行重定向吗?
在此之后,我尝试将配置添加到我的webmvc配置中,以强制所有RequestMappings始终使用参数alwaysUseFullPath=true,我是这样做的:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="3">
        <property name="alwaysUseFullPath" value="true" />
    </bean>

这一次,当我导航到 /question/list 时仍然无法加载正确的页面,但日志显示 Spring 至少识别出了正确的控制器,只是找不到方法(之前根据 URL 它甚至找不到控制器):
2011-08-09 18:02:27,885 [http-8080-3] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Matching patterns for request [/question/list] are [/question/**/list/, /question/**/list, /question/**/, /question/**]
2011-08-09 18:02:27,886 [http-8080-3] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapping [/question/list] to handler 'com.tmm.enterprise.microblog.controller.QuestionController@143c423'
2011-08-09 18:02:27,886 [http-8080-3] DEBUG org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/microblog/question/list] is: -1
2011-08-09 18:02:27,886 [http-8080-3] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'microblog' processing GET request for [/microblog/question/list]
2011-08-09 18:02:27,886 [http-8080-3] DEBUG org.springframework.web.servlet.handler.SimpleMappingExceptionResolver - Resolving exception from handler [com.tmm.enterprise.microblog.controller.QuestionController@143c423]: org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException: No matching handler method found for servlet request: path '/list', method 'GET', parameters map[[empty]]
2011-08-09 18:02:27,886 [http-8080-3] DEBUG org.springframework.web.servlet.handler.SimpleMappingExceptionResolver - Resolving to view 'resourceNotFound' for exception of type [org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException], based on exception mapping [.NoSuchRequestHandlingMethodException]
2011-08-09 18:02:27,887 [http-8080-3] DEBUG org.springframework.web.servlet.handler.SimpleMappingExceptionResolver - Exposing Exception as model attribute 'exception'

我觉得使用注释将控制器连接到URL似乎是一个相对简单的事情,但它没有正常工作 - 有没有人遇到过这个问题或者发现我犯了明显的错误?
更新

我在调查中取得了一些进展。

在我的web.xml文件中,我定义了如下的Servlet映射:

<servlet-mapping>
        <servlet-name>microblog</servlet-name>
        <url-pattern>/question/*</url-pattern>
    </servlet-mapping>

如果我删除此servlet映射(我仍然有一个servlet-mapping将所有.html映射到同一servlet),并将我使用的URL更改为/question/list.html,那么它就可以工作了(同时我将问题控制器中list()方法的@RequestMapping注释的方法级映射更改为/list.html)。
总之:
1. 我将servlet映射/question映射到Web上下文 2. 我将另一个映射/question映射到QuestionController 3. 我对我的列表方法进行了方法级别的映射/list
现在我不想让我的URL以.html结尾 - 有人知道我如何解决这个问题吗?似乎servlet-mapping从URL中剥离了匹配的/question字符串(因此/question/list不起作用,但/question/question/list可以工作)。

2
设置<url-pattern>/</url-pattern>以匹配没有HTML的URL。 - Gengzu
如果我使用它,那么所有的图像、css资源等都会被重定向到控制器,因此找不到它们(我的所有图像都在/images/...等路径下)- 所以当我加载页面时,没有图像或css样式。有什么办法可以将URL映射到控制器而不需要在URL中重复路径? - rhinds
1
将您的文件移动到上一级文件夹,而不是WEB-INF文件夹中。 - Gengzu
抱歉,我错了 - 我的图像、CSS等已经在WEB-INF目录级别的上一级。为什么当我添加<url-pattern>/</url-pattern>并导航到页面时,没有样式/图像出现? - rhinds
哦,使用 <mvc:resources mapping="/resources/**" location="/resources/" />。 - Gengzu
完美,那些东西完成了任务。如果您将其放在答案中,我会接受它。 - rhinds
3个回答

4

设置

<url-pattern>/</url-pattern> 

对于没有HTML的URL,使用

<mvc:resources mapping="/resources/**" location="/resources/" />

对于像.css、.jpg等资源。


2
您的控制器映射中不需要使用 /**。
将映射设置为 @RequestMapping(value = "/question") 就可以访问该控制器。 /list 将会添加到 /question 的末尾。
如果您像现在这样加上了 /**,就是告诉它要查找以 question 开头的任何内容,然后在末尾添加 /list
希望这能帮到您。

谢谢,我已经在做这个了,但是出于绝望,我尝试添加“/**”来模仿旧的XML配置方式。无论哪种情况,我仍然得到相同的结果。 - rhinds
我还更新了原始问题,并提供了一些关于web.xml servlet-mapping的发现。 - rhinds

0

我也遇到了这个问题,但不是开发而是调用Rest API时出现错误:"org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException: No matching handler method found for servlet request....."

我通过在Rest客户端工具中添加"Accept: application/json"到请求头解决了这个问题。希望能对你有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接