DispatcherServlet简介
Spring web MVC框架基于请求驱动,用一个核心Servlet转发请求到对应的Controller。然而Spring的DispatcherServlet并不仅仅拥有这些,因为Spring MVC框架集成了Spring IOC容器,因此,Spring MVC可以使用Spring 提供的其他功能。
DispatcherServlet的声明
DispatcherServlet继承了HttpServlet,是一个真实的Servlet,因此可以在web.xml文件中声明。另外还需要使用url匹配元件指定DispatcherServlet处理的请求。例如:
<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/example/*</url-pattern>
</servlet-mapping>
</web-app>
这个配置是指,所有以 /example 开始的请求都会被名为example的 DispatcherServlet所处理。不过我们也可以以编程方式配置上述DispatcherServlet,如:
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
ServletRegistration.Dynamic registration = container.addServlet("example", new DispatcherServlet());
registration.setLoadOnStartup(1);
registration.addMapping("/example/*");
}
}
不过这种方法很少用。
在Spring web MVC框架,每一个DispatcherServlet都拥有自己的WebApplicationContext,这个 、WebApplicationContext继承了根WebApplicationContext定义的所有bean。
DispatcherServlet在初始化时,Spring MVC会查找web应用WEB-INF目录下的[servlet-name]-servlet.xml并创建在此文件定义的bean。
比如上述的DispatcherServlet在web.xml里的配置如下:
<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/example/*</url-pattern>
</servlet-mapping>
</web-app>
这就要求应用程序在WEB-INF目录下有一个example-servlet.xml文件,在这个文件里,会包含Spring MVC的所有组件(beans)。
如果我们不想要这个默认的example-servlet.xml文件,我们可以通过定义servlet初始化参数来改变[servlet-name]-servlet.xml文件的路径,如下:
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
WebApplicationContext的专用bean
DispatcherServlet使用了其专用的bean来处理请求和渲染视图。不过这些bean并不需要我们去配置,默认已经配置好了,我们先简单看一下有哪些:
Bean type | Explanation |
---|---|
HandlerMapping | 将传入的请求映射到处理器。 |
HandlerAdapter | 帮助DispatcherServlet去调用请求所映射的handler。 |
HandlerExceptionResolver | 将异常映射到指定视图。 |
ViewResolver | 将视图名称解释为视图类型。 |
LocaleResolver & LocaleContextResolver | 解释客户端所在地区和其时区(本地化),以便提供国际化的视图。 |
ThemeResolver | 解释 web 程序可用的主题。 |
MultipartResolver | 解释multi-part请求,比如在html form里支持文件上传。 |
FlashMapManager | 存储和恢复从一个request到另一个request传递属性的”input”和”output”FlashMap |
DispatcherServlet处理顺序
DispatcherServlet处理一个传进来的请求时,会按照以下顺序来处理这个请求:
- 寻找WebApplicationContext,并将WebApplicationContext作为一个属性绑定到请求里。默认会以DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE
键绑定到请求里。
- 将本地化解析器绑定到请求里,以便在处理这个请求时,可以解析到客户端的地区。如果不需要本地化解析器,可以忽略这个步骤。
- 将主题解析其绑定到请求里,让elements,如视图,决定去使用哪一种主题。如果不需要使用主题,可以忽略这个步骤。
- 如果指定一个multipart file解析器,会检查这个请求是否包含multiparts请求。当发现了multiparts,这个请求会被封装为MultipartHttpServletRequest对象,提供给后续elements处理。
- 寻找合适的handler。如果找到这个handler,执行与这个 handler 关联的执行链,目的是准备一个model或渲染。
- 如果返回一个model,渲染相对应的视图。如果没有model返回(可能是因为preprocessorpostprocessor拦截了这个请求,也可能是权限问题),便不渲染任何视图,因为这个请求可能已执行完成。
DispatcherServlet初始化参数
在web.xml里,DispatcherServlet支持的初始化参数如下:
Parameter | Explanation |
---|---|
contextClass | WebApplicationContext的实现类,负责初始化Servlet所使用的上下文。默认使用XmlWebApplicationContext |
contextConfigLocation | 传给上下文(contextClass)使用的路径参数,用来说明在哪里查找上下文(配置文件)。支持以逗号分隔的多个路径参数。 |
namespace | WebApplicationContext命名空间。默认是 [servlet-name]-servlet。 |