Java Web Servlet 加载 web.xml 启动过程

web.xml启动

一、web.xml简单参数说明

1、display-name

    <!--定义了web应用的名称 
    	一般display-name都不用写的 ,只是一个标记
    -->
    <display-name>tcDemo1</display-name>

2、context-param

    <!-- spring config -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/*.xml </param-value>
    </context-param>

3、listener

   <!--ContextLoaderListener监听器的作用就是启动Web容器时,
   		自动装配ApplicationContext的配置信息
   	-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

4、filter

    <!-- 字符集过滤器 -->
    <filter>
        <filter-name>encodingFilter</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>
    
  <!--
  	   HiddenHttpMethodFilter过滤器
       restful风格编码   
       如果不加HiddenHttpMethodFilter过滤器 就不支持 put和delet
        <input type="hidden" name="_method" value="DELETE">
  -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>


    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <servlet-name>springMVC3</servlet-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>

5、servlet

    <!--
        //配置Spring MVC,指定处理请求的Servlet,有两种方式:
        1. 默认查找MVC配置文件的地址是:/WEB-INF/${servletName}-servlet.xml
        2. 可以通过配置修改MVC配置文件的位置,需要在配置DispatcherServlet时指定MVC配置文件的位置。
        这里使用的是第二种方式
    -->
    <!-- Springmvc的核心控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 指定springmvc的配置文件的地址
            servlet范围内的参数,只能在servlet的init()方法中取得,
            初始化servlet     getServletConfig().getInitParameter("initParam")
        -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring/*.xml</param-value>
        </init-param>
        <!--负数或者0代表延时加载,第一次调用的时候采取加载
            数字越小优先级越高
        -->
        <load-on-startup>0</load-on-startup>
    </servlet>
    

6、welcome-file-list

    <!--定义欢迎页面-->
    <!--如果index.html在/WEB-INF目录下,要配置成/WEB-INF/index.jsp
        如果index.html在/WEB-INF目录下,访问方法:
      127.0.0.1:8080/tcDemo1/ 可以访问,
      127.0.0.1:8080/tcDemo1/index.html 不可访问,不可以添加index.html
       根目录可以
    -->
    <welcome-file-list>
        <welcome-file>/WEB-INF/index.jsp</welcome-file>
    </welcome-file-list>

7、error-page

    <!--定义错误页面-->
    <error-page>
        <exception-type>java.lang.NullPointerException</exception-type>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/404.jsp</location>
    </error-page>

二、web.xml启动顺序

  1. 启动一个web项目,web容器(如tomcat)读取web.xml文件,读取其中的配置信息节点context-param、listener
  2. 容器将创建一个ServletContext(又称为:Servlet上下文),应用范围内即整个WEB项目都能使用这个Servlet上下文。
    a: 容器中所有的servlet都共享同一个ServletContext
    b:每个servlet都有它独有的serveltConfig信息,相互之间不共享
  3. 容器将< context-param >转化为键值对,并交给ServletContext。
  4. 容器创建< listener >中的类实例,即创建监听。(备注:listener定义的类可以是自定义的类但必须需要继承ServletContextListener)

1、web容器去读取web.xml文件,并且运行ContextLoaderListener监听器,该监听器因为实现了ServletContextListener接口,所以当发现容器生成了一个ServletContext实例的时候,便会执行ServletContextListener接口的初始化方法,在该初始化方法中根据contextConfigLocation指定的位置去读取spring的主要配置文件,然后生成web应用上下文WebApplicationContext,并且将其作为一个属性注入到ServletContext中。(作为servletContext的一个attribute,属性)并且在WebApplicationContext中保留了一个servletContext。

2、监听中会有contextInitialized(ServletContextEvent args)初始化方法
还有有一个contextDestroyed(ServletContextEvent event) 销毁方法。(用于关闭应用前释放资源,比如说数据库连接的关闭。)

ps:
触发contextInitialized方法,listener被调用(当Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent 事件,该事件由ServletContextListener 来处理。在 ServletContextListener 接口中定义了处理ServletContextEvent 事件的两个方法contextInitialized;contextDestroyed,web.xml有contextLoaderListener监听器,spring等框架实现了本监听器的接口方法)

  1. 初始化WebApplicationContext以后,启动了“业务层”的spring容器,并开始加载并初始化applicationContext配置文件中所扫描的类。
  2. 然后就是初始化filter,最后初始化servlet。

三、web.xml问题

  1. webApplicationContext和servletContext关系?

    web项目,WebApplicationContext的生成必须要在web容器存在的情况下才能实现,因为他需要ServletContext,而ServletContext是web容器生成的。

  2. context-param,listener,filter,servlet配置语句在web.xml中的顺序,改变web.xml位置顺序其启动顺序是否会变呢?

    启动顺序: ServletContext -> context-param(无顺序)-> listener(无顺序)-> filter(书写顺序) -> servlet(load-on-startup优先级)–>spring

    1、web.xml 的加载顺序是:[context-param -> listener -> filter -> servlet -> spring]

    2、web.xml节点的加载顺序与它们在web.xml中位置的先后无关。即使把servlet的配置放在最前面,其加载顺序还是会在最后。

    3、但是在同一类型的配置项中,其在web.xml的顺序会影响其启动的顺序,比如有两个filter,filter1在配置文件中先于filter2,则filter1先于filter2被加载实例化。

    4、某类配置节点而言,位置的先后是有要求的必须在后定义,否则当解析到时,它的还没有定义。

  3. applicationContext.xml和dispatcher-servlet.xml加载顺序?

    先加载applicationContext.xml 再加载dispatcher-servlet.xml

    1、applicationContext.xml 是Spring的全局配置文件,用来控制Spring特性,管理Bean的容器。是随ContextLoaderListener而加载的

    2、dispatcher-servlet.xml是SpringMVC中用作控制器,拦截器、转发view等作用。是随DispatcherServlet而加载的

web.xml配置

一、web.xml头定义

//web.xml v2.3
<?xml version="1.0" encoding="ISO-8859-1"?>  
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>  
   
</web-app> 


//web.xml v2.4
<?xml version="1.0" encoding="UTF-8"?>  
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"   
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
</web-app>


//web.xml v2.5
<?xml version="1.0" encoding="UTF-8"?>  
<web-app 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_5.xsd"  
    version="2.5">  
   
</web-app>


//web.xml v3.0
<?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">  
   
</web-app>


//Web4.0
//在SpringMVC中JSP页面通过${message}始终无法获取这个变量在Controller传递过来的值。
//偶然发现问题在于web.xml文件中声明的Web2.3不支持如上的变量引用,所以就创建了Web4.0的项目,将其开头声明替换成Web4.0的就解决了
<?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_4_0.xsd"
         version="4.0">
</web-app>

二、 web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
         version="3.0">

    <!--定义了web应用的名称   一般display-name都不用写的 ,只是一个标记-->
    <display-name>tcDemo1</display-name>

    <!--****************************上下文初始化参数***************************-->
    <!-- 全局应用参数   -->
    <!-- webapp.root"这个字符串可以随便写任何字符串。如果不配置默认值是"webapp.root"。
       可以用System.getProperty("webapp.root")来动态获项目的运行路径。
       一般返回结果例如:/usr/local/tomcat6/webapps/项目名

        通过getServletContext().getInitParameter("contextParam")的方式获取;
     -->
    <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>business.root</param-value>
    </context-param>
    <!-- spring config -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/*.xml</param-value>
    </context-param>

    <!--加载Log4J 配置文件  注意路径-->
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>WEB-INF/classes/log4j.properties</param-value>
    </context-param>

    <!--ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--Log4jConfigListener已经包含了WebAppRootListener的功能
        WebAppRootListener来监听器运行时的项目路径
    -->
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <!--定义欢迎页面-->
    <!--如果index.html在/WEB-INF目录下,要配置成/WEB-INF/index.jsp
        如果index.html在/WEB-INF目录下,访问方法:
      127.0.0.1:8080/tcDemo1/ 可以访问,
      127.0.0.1:8080/tcDemo1/index.html 不可访问,不可以添加index.html
       根目录可以
    -->
    <welcome-file-list>
        <welcome-file>/WEB-INF/index.jsp</welcome-file>
    </welcome-file-list>

    <!--定义错误页面-->
    <error-page>
        <exception-type>java.lang.NullPointerException</exception-type>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/404.jsp</location>
    </error-page>
    <error-page>
        <error-code>500</error-code>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>414</error-code>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>505</error-code>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>400</error-code>
        <location>/error.jsp</location>
    </error-page>


    <!--****************************过滤器配置*********************************-->
    <!-- 字符集过滤器 -->
    <filter>
        <filter-name>encodingFilter</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>

    <!--
        restful风格编码   如果不加HiddenHttpMethodFilter过滤器 就不支持 put和delet
        <input type="hidden" name="_method" value="DELETE">
     -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <servlet-name>springMVC3</servlet-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <!--
        //配置Spring MVC,指定处理请求的Servlet,有两种方式:
        1. 默认查找MVC配置文件的地址是:/WEB-INF/${servletName}-servlet.xml
        2. 可以通过配置修改MVC配置文件的位置,需要在配置DispatcherServlet时指定MVC配置文件的位置。
        这里使用的是第二种方式
    -->
    <!-- Springmvc的核心控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 指定springmvc的配置文件的地址
            servlet范围内的参数,只能在servlet的init()方法中取得,
            初始化servlet     getServletConfig().getInitParameter("initParam")
        -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring/*.xml</param-value>
        </init-param>
        <!--负数或者0代表延时加载,第一次调用的时候采取加载
            数字越小优先级越高
        -->
        <load-on-startup>0</load-on-startup>
    </servlet>
    <!-- 这里有三种配置url-pattern方案
           1、*.do:后缀为.do的请求才能够访问到该servlet[用这个]
           2、/ :所有请求都能够访问到该servlet(除jsp),包括静态请求(处理会有问题,不用)
           3、/* :有问题,因为访问jsp也会到该servlet,而访问jsp时,我们不需要这样,也不用
     -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

参考资料:

https://blog.youkuaiyun.com/qq_40693828/article/details/81086588?biz_id=102
https://www.cnblogs.com/roy-blog/p/7656834.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值