您的标准Spring MVC应用程序将通过您在Servlet容器中注册的DispmenterServlet
为所有请求提供服务。
查看它和(如果可用)注册到一个特殊bean,它需要设置其请求服务逻辑。这些豆子在文档中进行了描述。DispatcherServlet
ApplicationContext
ApplicationContext
ContextLoaderListener
可以说是最重要的,处理程序映射
类型的豆子
对处理程序的传入请求以及基于某些条件的前处理器和后处理器(处理程序拦截器)的列表,其详细信息因实现而异。最流行的实现支持带注释的控制器,但也存在其他实现。HandlerMapping
HandlerMapping
的javadoc进一步描述了实现必须如何表现。
查找此类型的所有 bean,并按某种顺序(可自定义)注册它们。在为请求提供服务时,循环遍历这些对象,并使用getHandler
测试每个对象,以找到可以处理传入请求的对象,表示为标准。从 4.3.x 开始,如果它找不到任何内容,它会记录您看到的警告DispatcherServlet
DispatcherServlet
HandlerMapping
HttpServletRequest
未找到名为 SomeName 的 URI 的 HTTP 请求的映射[/some/path]
DispatcherServlet
并抛出 NoHandlerFoundException
或立即提交带有 404 Not Found 状态代码的响应。
为什么没有找到可以处理我的请求的?DispatcherServlet
HandlerMapping
最常见的实现是 RequestMappingHandlerMapping
,它将 Bean 注册为处理程序(实际上是它们的带注释的方法)。您可以自己声明此类型的Bean(使用或或其他机制),也可以使用内置选项。这些是:HandlerMapping
@Controller
@RequestMapping
@Bean
<bean>
- 使用 为类添加批注。
@Configuration
@EnableWebMvc
- 在 XML 配置中声明成员。
<mvc:annotation-driven />
正如上面的链接所描述的,这两个都将注册一个bean(以及一堆其他东西)。但是,如果没有处理程序,a 并不是很有用。 需要一些bean,所以你也需要通过Java配置中的方法或XML配置中的声明,或者通过组件扫描任何一个带注释的类来声明这些bean。确保这些豆子存在。RequestMappingHandlerMapping
HandlerMapping
RequestMappingHandlerMapping
@Controller
@Bean
<bean>
@Controller
如果您收到警告消息和 404,并且您已正确配置了上述所有内容,则您将请求发送到错误的 URI,该 URI 未由检测到的带注释的处理程序方法处理。@RequestMapping
该库提供其他内置实现。例如,BeanNameUrlHandlerMapping
mapsspring-webmvc
HandlerMapping
从 URL 到名称以斜杠 (“/”) 开头的 Bean
你总是可以写自己的。显然,您必须确保要发送的请求至少与已注册的 HandlerMapping
对象的处理程序之一匹配。
如果您没有隐式或显式注册任何bean(或者如果expceptAllHandlerMappings
是),则注册一些默认值。这些在 DispatcherServlet.properties
中定义,与类位于同一包中。它们是和DefaultAnnotationHandlerMapping
(类似于但已弃用)。HandlerMapping
true
DispatcherServlet
DispatcherServlet
BeanNameUrlHandlerMapping
RequestMappingHandlerMapping
调试
Spring MVC 将记录通过 注册的处理程序。例如,赞RequestMappingHandlerMapping
@Controller
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
将在 INFO 级别记录以下内容
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
这描述了注册的映射。当您看到未找到任何处理程序的警告时,请将消息中的 URI 与此处列出的映射进行比较。@RequestMapping
中指定的所有限制必须匹配,Spring MVC 才能选择处理程序。
其他实现记录自己的语句,这些语句应提示其映射及其相应的处理程序。HandlerMapping
同样,在 DEBUG 级别启用 Spring 日志记录,以查看哪些 Bean Spring 寄存器。它应该报告它找到哪些带注释的类,它扫描哪些包,以及它初始化了哪些bean。如果预期的不存在,请检查您的配置。ApplicationContext
其他常见错误
A 只是一个典型的 Java EE Servlet
。您可以使用典型的声明注册它,或者直接通过WebApplicationInitializer
中的ServletContext#addServlet
,或者使用Spring boot使用的任何机制来注册它。因此,您必须依赖于 Servlet 规范中指定的 url 映射逻辑,请参阅第 12 章。另请参见DispatcherServlet
<web.xml>
<servlet-class>
<servlet-mapping>
考虑到这一点,一个常见的错误是使用 的 url 映射注册 ,从处理程序方法返回视图名称,并期望呈现 JSP。例如,考虑一个处理程序方法,如DispatcherServlet
/*
@RequestMapping
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
使用内部资源查看解决方案
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
您可能希望将请求转发到路径 中的 JSP 资源。这不会发生。相反,假设上下文名称为 ,将报告/WEB-INF/jsps/example-view-name.jsp
Example
DisaptcherServlet
未找到名称为“调度程序”的 URI 的 HTTP 请求的映射[/Example/WEB-INF/jsps/example-view-name.jsp]
DispatcherServlet
由于 映射到并匹配所有内容(完全匹配项除外,它们具有较高的优先级),因此将选择 从 JstlView
处理 (由 返回)。在几乎所有情况下,DispatcherServlet
都不会被配置为处理这样的请求。DispatcherServlet
/*
/*
DispatcherServlet
forward
InternalResourceViewResolver
相反,在这种简单的情况下,您应该注册 to ,将其标记为默认 servlet。默认 servlet 是请求的最后一个匹配项。这将允许您的典型 Servlet 容器在尝试使用默认 Servlet 之前,选择映射到 的内部 Servlet 实现来处理 JSP 资源(例如,Tomcat 具有 JspServlet
)。DispatcherServlet
/
*.jsp
这就是您在示例中看到的内容。