Spring配置web.xml的<servlet>标签

本文深入解析Spring MVC架构中的DispatcherServlet初始化流程,包括配置解析、核心类DispatcherServlet的继承关系、关键初始化方法及其背后的Spring框架机制,以及一系列组件如MultipartResolver、LocaleResolver等的初始化过程。

在web.xml中配置

<servlet>
    <servlet-name>citic</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/frm-servlet.xml,/WEB-INF/app-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

先看继承关系:

public class DispatcherServlet extends FrameworkServlet 
public abstract class FrameworkServlet extends HttpServletBean
public abstract class HttpServletBean extends HttpServlet

知道最终继承的是javax.servlet.http.HttpServlet类,大家都知道在初始化一个Servlet的时候会默认调用定义的int()方法,所有肯定我们要在这个方法上做文章,这个方法在HttpServletBean 中重写。
类中的重要代码如下:

@Override
    public final void init() throws ServletException {
        // 交给子类FrameworkServlet 实现
        initServletBean();

到FrameworkServlet 中initServletBean内部代码:

this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
protected WebApplicationContext initWebApplicationContext() {
    onRefresh(wac);
}           

好了,onRefresh是最终要在我们接触到的类DispatcherServlet中实现的方法,直接定位DispatcherServlet类的内部代码。

@Override
    protected void onRefresh(ApplicationContext context) {
        initStrategies(context);
    }
    /**
     * Initialize the strategy objects that this servlet uses.
     * <p>May be overridden in subclasses in order to initialize further strategy objects.
     * <p>这是最终执行的方法刷新,,它是在WebApplicationContext已经存在的情况下进行的,也就意味着在初始化它的时候,
     *   IOC容器应该已经工作了,这也是我们在web.xml中配置Spring的时候,需要把DispatcherServlet的 load-on-startup的属性配置为2的原因。 
     */
    protected void initStrategies(ApplicationContext context) {
        initMultipartResolver(context);
        initLocaleResolver(context);
        initThemeResolver(context);
        ////初始化Handler映射,例如@RequestMapping(value = "/something", method = RequestMethod.PUT)
        initHandlerMappings(context);
        initHandlerAdapters(context);
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
        initFlashMapManager(context);
    }

哦了,看到这么多初始化我们就放心了,因为这里的每一个方法都是Spring的大牛之处,其中不乏大量的使用注解的声明方式(注解的分享在Spring注解一文说明)
下面我们来一个一个的分享下上面的一系列init操作。

&& initMultipartResolver(context)
作用:初始化Spring的文件上传解析器。

private void initMultipartResolver(ApplicationContext context) {
            this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);

只是简单的从ApplicationContext (相当于bean工厂)得到需要类型的对象。

&&initLocaleResolver(context)
web应用程序支持国际化,必须识别每个用户的首选区域,并根据这个区域显示内容。
在Spring MVC应用程序中,用户的区域是通过区域解析器来识别的,它必须实现LocaleResolver接口(在Spring-LocaleResolver中详细讲解)。

private void initLocaleResolver(ApplicationContext context) {
    this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
            …………
    catch (NoSuchBeanDefinitionException ex) {
            // We need to use the default.
            this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);

这里注意如果没有会得到默认的localeResolver ,定义实在属性文件DispatcherServlet.propertiesorg.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver就是AcceptHeaderLocaleResolver

&&ThemeResolver主题解析
初始化过程和上面的LocaleResolver方式是一样的,如果没有定义会得到默认配置的org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

&&initHandlerMappings
作用:初始化与用户请求相关联的控制器

// 这里找到所有在上下文中定义的HandlerMapping,同时把他们排序  
// 因为在同一个上下文中可以有不止一个handlerMapping,所以我们把他们都载入到一个链里进行维护和管理 
Map<String, HandlerMapping> matchingBeans =             BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);

很简单,就是从bean工厂得到给定类型的所有的bean。Spring中默认定义的为BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping
*Spring是怎样加载用户定义的HandlerMapping将在《Spring MVC-HandlerMapping》中分享,点击这里前往Spring MVC-HandlerMapping

&&initHandlerAdapters
作用:处理用户的请求。
HandlerMappings是找到用户的请求对应的处理类和函数,HandlerAdapter任务是执行找到的函数,在执行之前有一系列的初始化操作。
Spring中默认定义的为HandlerAdapter为HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、AnnotationMethodHandlerAdapter
*Spring是怎样加载用户定义的HandlerAdapter将在《Spring MVC-HandlerAdapter》中分享,点击网址前往Spring MVC-HandlerAdapter

&& initHandlerExceptionResolvers
作用:初始化异常解析器,就是在handle请求的时候对于产生的异常如何处理,其实就是对response对象的设置,还有就是返回ModelAndView对象。
*Spring是怎样加载用户定义的HandlerAdapter将在《Spring MVC-HandlerExceptionResolver》中分享,点击网址前往Spring MVC-HandlerExceptionResolver

&& initRequestToViewNameTranslator
作用:将请求转换为对应的视图名称
Spring中默认定义的为HandlerAdapter为AnnotationMethodHandlerExceptionResolver、ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver。

Spring是怎样加载用户定义的HandlerAdapter将在《Spring MVC-RequestToViewNameTranslator》中分享

&&initViewResolvers(context)
作用:视图解析
Spring中默认定义的为ViewResolver为InternalResourceViewResolver
Spring是怎样加载用户定义的HandlerAdapter将在《Spring MVC-ViewResolver》中分享

<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.3" 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_2_3.xsd"> <display-name>Archetype Created Web Application</display-name> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <!-- 配置spring资源 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:application.xml</param-value> </context-param> <!-- 乱码问题 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--配置springmvc DispatcherServlet接收到的http请求通过DispatcherServlet进行分发。--> <servlet> <servlet-name>note</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!--Sources标注的文件夹下需要新建一个spring文件夹--> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>note</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>检查代码修改正确
06-07
### 验证 `web.xml` 配置文件中的 Spring MVC、字符编码过滤器和欢迎文件列表等配置是否正确 #### 1. Spring MVC 配置验证 在 `web.xml` 中配置 Spring MVC 的核心是通过 `DispatcherServlet` 来实现的。以下是一个标准的配置示例,确保配置符合规范: ```xml <servlet> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMvc</servlet-name> <url-pattern>*.zxh</url-pattern> </servlet-mapping> ``` - 确保 `<servlet-name>` 和 `<servlet-mapping>` 中的名称一致[^3]。 - 如果未指定 `contextConfigLocation` 参数,则默认会加载 `/WEB-INF/springMvc-servlet.xml` 文件。 #### 2. 字符编码过滤器配置验证 字符编码过滤器通常用于解决请求参数和响应内容的编码问题。以下是一个标准的配置示例: ```xml <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` - 确保 `encoding` 参数设置为 `utf-8`,以支持多语言环境[^2]。 - `forceEncoding` 参数应设置为 `true`,以强制覆盖客户端可能设置的不正确编码[^2]。 #### 3. 欢迎文件列表配置验证 欢迎文件列表用于定义当用户访问一个目录时,服务器返回的默认文件。以下是一个标准的配置示例: ```xml <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> ``` - 确保列出的文件名与实际项目中存在的一致。 - 如果项目中有多个入口文件(如 `index.html` 和 `index.jsp`),可以按优先级顺序列出。 #### 4. 其他常见问题检查 - **语法错误**:确保所有标签都正确闭合,例如 `<filter>` 必须有对应的 `</filter>`[^3]。 - **路径问题**:如果指定了 `contextConfigLocation`,确保路径下的配置文件存在且内容正确[^3]。 - **加载顺序**:`<listener>` 标签通常需要放在 `<servlet>` 标签之前,以确保上下文初始化顺序正确[^3]。 ```xml <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> ``` #### 示例完整配置 以下是一个完整的 `web.xml` 配置示例,结合了 Spring MVC、字符编码过滤器和欢迎文件列表的配置: ```xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!-- Spring 上下文加载 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 字符编码过滤器 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Spring MVC 配置 --> <servlet> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMvc</servlet-name> <url-pattern>*.zxh</url-pattern> </servlet-mapping> <!-- 欢迎文件列表 --> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值