在典型的 Spring MVC 应用中,我们会需要 DispatcherServlet 和 ContextLoader-Listener。AbstractAnnotationConfigDispatcherServletInitializer 会自动注册它们,但是如果需要在 web.xml 中注册的话,那就需要我们自己来完成这项任务了。 如下是一个基本的 web.xml 文件,它按照传统的方式搭建了 Dispatcher-Servlet 和 ContextLoaderListener。
程序清单 7.3 在 web.xml 中搭建 Spring MVC
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
就像我在第 5 章曾经介绍过的,ContextLoaderListener 和 DispatcherServlet 各自都会加载一个 Spring 应用上下文。上下文参数 contextConfigLocation 指定了一个 XML 文件的地址,这个文件定义了根应用上下文,它会被 ContextLoader-Listener 加载。如程序清单 7.3 所示,根上下文会从 /WEB-INF/spring/rootcontext.xml
中加载 bean 定义。
DispatcherServlet 会根据 Servlet 的名字找到一个文件,并基于该文件加载应用上下文。在程序清单 7.3 中,Servlet 的名字是 appServlet,因此 Dispatcher-Servlet 会从 /WEBINF/appServlet-context.xml
文件中加载其应用上下文。
如果你希望指定 DispatcherServlet 配置文件的位置的话,那么可以在 Servlet 上指定一个 contextConfigLocation 初始化参数。例如,如下的配置中,DispatcherServlet 会从 /WEB-INF/spring/appServlet/servlet-context.xml
加载它的 bean:
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/appServlet/servlet-context.xml
</param-value>
</init-parma>
<load-on-startup>1</load-on-startup>
</servlet>
当然,上面阐述的都是如何让 DispatcherServlet 和 ContextLoaderListener 从 XML 中加载各自的应用上下文。但是,在本书中的大部分内容中,我们都更倾向于使用 Java 配置而不是 XML 配置。因此,我们需要让 Spring MVC 在启动的时候,从带有 @Configuration 注解的类上加载配置。
要在 Spring MVC 中使用基于 Java 的配置,我们需要告诉 DispatcherServlet 和 ContextLoaderListener 使用 AnnotationConfigWebApplicationContext,这是一 个 WebApplicationContext 的实现类,它会加载 Java 配置类,而不是使用 XML。要实现这种配置,我们可以设置 contextClass 上下文参数以及 DispatcherServlet 的初始化参数。如下的程序清单展现 了一个新的 web.xml,在这个文件中,它所搭建的 Spring MVC 使用基于 Java 的 Spring 配置:
程序清单 7.4 设置 web.xml 使用基于 Java 的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
com.habuma.spitter.config.RootConfig
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
com.habuma.spitter.config.WebConfigConfig
</param-value>
</context-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
现在我们已经看到了如何以多种不同的方式来搭建 Spring MVC,那么接下来我们会看一下如何使用 Spring MVC 来处理文件上传。