web.xml详解:元素含义及加载顺序
收藏自:http://wsmajunfeng.iteye.com/blog/1106927
web.xml即部署描述符,其包含了很多描述servlet/JSP应用的各个方面的元素,如servlet注册、servlet映射以及监听器注册。
(一) XML头
??? 部署描述符从下面的XML头开始:
??? 这个头指定了XML的版本号以及所使用的编码。
(二) DOCTYPE声明
??? 头的下面是DOCTYPE声明:
??? 这段代码指定文件类型定义(DTD),可以通过它检查XML文档的有效性。下面显示的<!DOCTYPE>元素有几个特性,这些特性告诉我们关于DTD的信息:
● web-app定义该文档(部署描述符,不是DTD文件)的根元素
● PUBLIC意味着DTD文件可以被公开使用
● "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"意味着DTD由Sun Microsystems, Inc.维护。 该信息也表示它描述的文档类型是DTD Web Application 2.3,而且DTD是用英文书写的。
● URL"http://java.sun.com/dtd/web-app_2_3.dtd"表示D文件的位置。
??? 注意:在部署描述符中, <!--?-->用于注释。
(三) web-app
??? 部署描述符的根元素是web-app。DTD文件规定,web-app元素的子元素的语法如下:
3. description元素
??? 可以使用description元素来提供有关部署描述符的信息。XML编辑器可以使用description元素的值。
5. context-param元素
??? context-param元素含有一对参数名和参数值,用作应用的servlet上下文初始化参数。参数名在整个Web应用中必须是惟一的。
6. filter元素
??? filter元素用于指定Web容器中的过滤器。在请求和响应对象被servlet处理之前或之后,可以使用过滤器对这两个对象进行操作。利用下一节介绍 的filter-mapping元素,过滤器被映射到一个servlet或一个URL模式。这个过滤器的filter元素和filter-mapping 元素必须具有相同的名称。
7. filter-mapping元素
??? filter-mapping元素用来声明Web应用中的过滤器映射。过滤器可被映射到一个servlet或一个URL模式。将过滤器映射到一个 servlet中会造成过滤器作用于servlet上。将过滤器映射到一个URL模式中则可以将过滤器应用于任何资源,只要该资源的URL与URL模式匹 配。过滤是按照部署描述符的filter-mapping元素出现的顺序执行的。
8. listener元素
??? listener元素用来注册一个监听器类,可以在Web应用中包含该类。使用listener元素,可以收到事件什么时候发生以及用什么作为响应的通知。
9. servlet元素
???? servlet元素用来声明一个servlet。
10. servlet-mapping 元素
??? 将URL模式映射到某个servlet。
12. mime-mapping元素
??? mime-mapping元素将mime类型映射到扩展名。
13. welcome-file-list元素
??? 当用户在浏览器中输入的URL不包含某个servlet名或JSP页面时,welcome-file-list元素可指定显示的默认文件。
??? 如果用户键入的URL不包含servlet名称、JSP页面或其他资源,则不会在应用目录中找到main.html文件,这时就会显示jsp目录下的welcome.jsp文件。
14. error-page元素
??? error-page元素用于将一段错误代码或一个异常类型映射到Web应用中的资源路径,从而在产生特殊的HTTP错误或指定的Java异常时,将显示相关的资源。
15. taglib元素
??? taglib元素描述JSP定制标记库。
??? local元素包含EJB本地接口的完全限定的名称。Local-home元素包含EJB本地home接口的完全限定的名称。
(四) web.xml中servlet、filter、listener等元素的加载顺序
??? 首先可以肯定的是,加载顺序与它们在 web.xml 文件中的先后顺序无关。即不会因为 filter 写在 listener 的前面而会先加载 filter。最终得出的结论是:listener -> filter -> servlet。
??? 同时还存在着这样一种配置节:context-param,它用于向 ServletContext 提供键值对,即应用程序上下文信息。我们的 listener, filter 等在初始化时会用到这些上下文中的信息,那么 context-param 配置节是不是应该写在 listener 配置节前呢?实际上 context-param 配置节可写在任意位置,因此真正的加载顺序为:context- param -> listener -> filter -> servlet。
??? 对于某类配置节而言,与它们出现的顺序是有关的。以 filter 为例,web.xml 中当然可以定义多个 filter,与 filter 相关的一个配置节是 filter-mapping,这里一定要注意,对于拥有相同 filter-name 的 filter 和 filter-mapping 配置节而言,filter-mapping 必须出现在 filter 之后,否则当解析到 filter-mapping 时,它所对应的 filter- name 还未定义。web 容器启动时初始化每个 filter 时,是按照 filter 配置节出现的顺序来初始化的,当请求资源匹配多个 filter-mapping 时,filter 拦截资源是按照 filter-mapping 配置节出现的顺序来依次调用 doFilter() 方法的。?
??? servlet 同 filter 类似 ,此处不再赘述。?
??? 由此,可以看出,web.xml 的加载顺序是:context- param -> listener -> filter -> servlet ,而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。
??? 更细致的概括是:
??? 初始化ServletContext--->初始化各个listener--->触发ServletContextAttributeListener的attributeAdded事件---->触发ServletContextListener的contextInitialized--->初始化filter(按照filter-map的先后顺序初始化)------>根据servlet的load-on-startup的值进行初始化,值越小就越早初始化,小于0启动不初始化有请求才初始化。