Java SpringMVC请求映射

Java SpringMVC请求映射,java,spring,Java,Spring,我正处于学习使用SpringMVC的早期阶段。我创建了一个控制器,并对其应用了RequestMapping注释。当我运行该项目时,索引页面在index.htm处按预期显示,但是当我导航到应该指向我的控制器的URI时,我得到一个404错误,即使控制器似乎已被Spring检测到并启动。请帮助我理解我在这里没有掌握的东西: 这是我的web.xml: <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns=

我正处于学习使用SpringMVC的早期阶段。我创建了一个控制器,并对其应用了
RequestMapping
注释。当我运行该项目时,索引页面在
index.htm
处按预期显示,但是当我导航到应该指向我的控制器的URI时,我得到一个404错误,即使控制器似乎已被Spring检测到并启动。请帮助我理解我在这里没有掌握的东西:

这是我的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
    <session-timeout>
        30
    </session-timeout>
</session-config>
<welcome-file-list>
    <welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
编辑:这是我的浏览器显示的内容:

您的dispatcher servlet似乎没有被正确引用

替换:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

调度员
org.springframework.web.servlet.DispatcherServlet
2.
与:


调度员
org.springframework.web.servlet.DispatcherServlet
上下文配置位置
[在此处插入dispatcher servlet的路径]
1.
然后移动:

<context:spring-configured/>

<context:component-scan base-package="org.blah.blah"/>


从applicationContext到DispatcherServlet

我对的评论错了一半

当您在servlet配置中指定
时,Spring会注册一个
RequestMappingHandlerMapping
bean,该bean用于收集和映射所有
@Controller
处理程序方法,即用
@RequestMapping
注释的方法

它通过查看当前上下文中的所有bean来实现这一点。请记住,当您使用
DispatcherServlet
加载上下文时,将其称为servlet上下文,如果上下文是由
ContextLoaderListener加载的,则将其称为根上下文,根上下文将成为servlet上下文的父上下文默认情况下,
RequestMappingHandlerMapping
bean不查看作为servlet上下文父级的根上下文

在您的例子中,
@Controller
bean是在根上下文(您的applicationContext.xml)中隐式声明的,因为
扫描带有注释的类
@Component
或其任何专门化(
@Controller
)并为它们创建bean。因此,这些bean是在根上下文中注册的,
RequestMappingHandlerMapping
在根上下文中找不到它们

相反,如果您在servlet上下文中声明
,则会在servlet上下文中创建
@Controller
(和其他)bean,这些bean可用于
RequestMappingHandlerMapping
,然后可以注册它们以处理请求

请注意,
本身对MVC堆栈没有任何作用。它需要进一步的配置,如
。您应该指定在servlet上下文中包含特定于servlet的bean,在根上下文中包含应用程序范围的bean的包

以下是一些文献:


您的上下文路径是什么?您点击的导致404的URL是什么?@SotiriosDelimanolis我的上下文路径是
/blah
,我已经尝试了十几个不同的URL-
/blah/hello
是我希望使用的URL。。。对吗?我知道你试图隐藏真实姓名,但请确保控制器类和配置中的所有内容一致。还有,你得到的404,Tomcat的错误消息是怎么说的?@SotiriosDelimanolis-有趣的是:没有错误消息-它只是空白。描述中说“请求的资源不可用”。实际上,我并不想在这里隐藏任何东西——为了弄清楚发生了什么,我创建了一个名为
blah
的实际包。上面的内容是直接从我的源文件c/p生成的。当您的浏览器给出404时,它说缺少什么?它应该给出一个资源路径。不,默认情况下,
DispatcherServlet
将查找名为
-servlet.xml
的文件。在这种情况下,2的启动负载将与1具有相同的效果,尽管这很奇怪。组件扫描不一定要在servlet上下文中。只要它创建了一个
mvc:annotation-driven
可以看到的bean。通常我同意,但我总是发现在出现这样的错误时尽可能明确是有用的。依赖构建来自动处理事情有时会导致问题,但明确声明目标意味着如果有问题,则是您键入的内容有问题。将两行
移到dispatcher servlet后,成功了!为了帮助我了解这里发生的事情,你能解释一下我通过移动这两条线到底做了什么,以及它为什么起作用吗?非常感谢你的解释,这很有帮助。我接受了另一个答案,因为这是解决问题的方法,但我投了你的一票!
@Controller
@RequestMapping(value = "/hello")
public class Ctrl {

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public String hello(){
    return "hello!";
    }

}
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>[insert the path to your dispatcher-servlet here]</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<context:spring-configured/>

<context:component-scan base-package="org.blah.blah"/>