当我们启动一个WEB项目容器时,容器包括(JBoss,Tomcat等)。首先会去读取web.xml配置文件里的配置,当这一步骤没有出错并且完成之后,项目才能正常的被启动起来。
web.xml 配置文件 超详细说明!!!
web.xml的加载过程配置详解
1、web.xml
加载顺序为:context-param -> listener -> filter -> servlet
其中,如果web.xml中出现了相同的元素,则按照在配置文件中出现的先后顺序来加载。
(1) context-param
配置的是整个web应用的上下文初始化参数,详见 SpringMVC配置文件(传统xml配置)详解
如果想要获得参数值,可以在servlet中调用: getServletConfig().getServletContext().getInitParameter(); 在web应用部署完成以后,值没法改变。
(2) listener
监听器就是在application,session,request三个对象创建,销毁,或者往其中添加修改删除属性时自动执行代码的功能组件。Listener是Servlet的监听器,可以监听客户端的请求,服务端的操作等。详见Listener监听器
监听器 - session 销毁
Listener的分类
1)ServletContextListener接口:用于对Servlet整个上下文进行监听(创建,销毁)。
Spring提供ServletContextListener接口的一个实现类ContextLoaderListener监听器,该类可以作为Listener使用,在启动Tomcat容器的时候,该类的作用就是自动装载ApplicationContext的配置信息,如果没有设置contextConfigLocation的初始参数则会使用默认参数WEB-INF路径下的application.xml文件。如果需要自定义读取多个配置文件或者修改默认路径,则可以在web.xml中设置。
ContextLoaderListener会读取这些XML文件并产生WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样只要我们得到Servlet就可以得到WebApplicationContext对象,并利用这个对象访问spring容器管理的bean。详见 SpringMVC配置文件(传统xml配置)详解
2)HttpSessionListener接口:对session的整体状态的监听。
以下两种情况下就会发生sessionDestoryed(会话销毁)事件:
1.执行session.invalidate()方法时。 ---不会调用sessionDestoryed??只清除session对象中的所有信息,清除指定属性信息用removeAttribute()。例如:session.setAttribute("name", "iverson");session.removeAttribute("name");
2.如果用户长时间没有访问服务器,超过了会话最大超时时间,服务器就会自动销毁超时的session。
设置Session有效时间的三种方式
session-config 用于设置容器的session参数,比如:
(3)直接在应用服务器中设置,如果是tomcat,可以在tomcat目录下conf/web.xml中找到元素,tomcat默认设置是30分钟,只要修改这个值就可以了。
Ps:优先级:(1)>(2)>(3)。
3)ServletRequestListener:用于对Request请求进行监听(创建,销毁)。
(3) filter
Filter可认为是Servlet的一种“变种”,它主要用于对用户请求(HttpServletRequest)进行预处理,也可以对服务器响应(HttpServletResponse)进行后处理,是个典型的处理链。它与Servlet的区别在于:它不能直接向用户生成响应。完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。详见JavaWeb中filter的详解及应用案例
WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
filter-mapping即过滤器映射。过滤器可被映射到一个servlet或一个URL模式。将过滤器映射到一个servlet中会造成过滤器作用于servlet上。将过滤器映射到一个URL模式中则可以将过滤器应用于任何资源,只要该资源的URL与URL模式匹配。
< filter-name>Filter的名称< /filter-name> ------定义Filter的名称
< url-pattern>URL< /url-pattern> ---Filter所对应的URL.例如:< url-pattern>/Filter/Hello< /url-pattern>
< servlet-name>Servlet的名称< servlet-name> -----定义servlet的名称
< dispatcher>REQUEST|INCLUDE|FORWARD|ERROR< /dispatcher>
设定Filter对应的请求方式,有RQUEST,INCLUDE,FORWAR,ERROR四种,默认为REQUEST
Filter接口中有一个doFilter方法,当开发人员编写好Filter类实现doFilter方法,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前(服务器内部对资源的访问机制决定的),都会先调用一下filter的doFilter方法。
Filter的生命周期和Servlet一样,Filter的创建和销毁也是由WEB服务器负责。不过与Servlet区别的是,它是1>在应用启动的时候就进行装载Filter类(与Servlet的load-on-startup配置效果相同)。2>容器创建好Filter对象实例后,调用init()方法。接着被Web容器保存进应用级的集合容器中去了等待着,用户访问资源。3>当用户访问的资源正好被Filter的url-pattern拦截时,容器会取出Filter类调用doFilter方法,下次或多次访问被拦截的资源时,Web容器会直接取出指定Filter对象实例调用doFilter方法(Filter对象常驻留Web容器了)。4>当应用服务被停止或重新装载了,则会执行Filter的destroy方法,Filter对象销毁。注意:init方法与destroy方法只会直接一次。
(4) servlet
Servlet通常称为服务端小程序,是服务端的程序,用于处理及响应客户的请求。Servlet是一个特殊的Java类,创建Servlet类自动继承HttpServlet。客户端通常只有GET和POST两种请求方式,Servlet为了响应这两种请求,必须重写doGet()和doPost()方法。大部分时候,Servlet对于所有的请求响应都是完全一样的,此时只需要重写service()方法即可响应客户端的所有请求。
创建Servlet实例有两个时机:
客户端第一次请求某个Servlet时,系统创建该Servlet的实例,大部分Servlet都是这种Servlet;
web应用启动时立即创建Servlet实例,即
1(实例化并调用其init()方法)。 (一般不会被容器销毁,它可以服务于多个用户的请求)
每个Servlet的运行都遵循如下生命周期:
(1)创建Servlet实例。
(2)Web容器调用Servlet的init()方法,对Servlet进行初始化。
(3)Servlet初始化之后,将一直存在与容器之中,用于响应客户端请求,如果客户端发送GET请求,容器调用 Servlet的doGet()方法处理并响应请求;如果客户端发送POST请求,容器调用Servlet的doPost()方法处理并响应请 求。或者统一使用service()方法处理来响应用户请求。
(4)Web容器决定销毁Servlet时,先调用Servlet的destory()方法,通常在关闭Web应用时销毁Servlet实例。
Servlet的配置:
为了让Servlet能响应用户请求,还必须将Servlet配置在web应用中,配置Servlet需要修改web.xml文件。从Servlet3.0开始,配置Servlet有两种方式:
(1)在Servlet类中使用基于注解的方式进行配置:@WebServlet
(2)在web.xml文件中进行配置。
init-param:配置的key/value会被设置到该servlet对应的servletConfig对象。ServletConfig提供方法:java.lang.String.getInitParameter(java.lang.String name):用于获取初始化参数。
注意:不同于ServletContxt,每个servlet 都会有自己的servletConfig。部署完成后,参数值不能变。 ServletConfig获取配置参数的方法和ServletContext获取配置参数的方法完全一样,只是ServletConfig是取得当前Servlet的配置参数,而ServletContext是获取整个web应用的配置参数。
load-on-startup:用来确定servlet的加载时间。如果未设置或者为负数,则在该servlet对应的第一个用户请求到来时,才加载servlet类,并调用init()。如果为正数或者0,则在web应用部署后就加载servlet。其数字的大小又标识了加载的顺序,值越小越早被加载,如果值相等,就先在web.xml声明的先加载。