⼀、l是什么?
⾸先 l 是java web 项⽬的⼀个重要的配置⽂件,但是l⽂件并不是Java web⼯程必须的。
所在位置项⽬名/web/l,如下图所⽰
其实,l的模式(Schema)⽂件中定义了多少种标签元素,l中就可以出现它的模式⽂件所定义的标签元素,它就能拥有定义出来的那些功能。
⼆、l详解:
l加载过程(步骤)
⾸先简单讲⼀下,l的加载过程。当启动⼀个WEB项⽬时,容器包括(JBoss、Tomcat等)⾸先会读取项⽬l配置⽂件⾥的配置,当这⼀步骤没有出错并且完成之后,项⽬才能正常地被启动起来。
1. 启动WEB项⽬的时候,容器⾸先会去它的配置⽂件l读取两个节点: <listener></listener>和<context-param></context-param>。
2. 紧接着,容器创建⼀个ServletContext(application),这个WEB项⽬所有部分都将共享这个上下⽂。
3. 容器以<context-param></context-param>的name作为键,value作为值,将其转化为键值对,存⼊ServletContext。
4. 容器创建<listener></listener>中的类实例,根据配置的class类路径<listener-class>来创建监听,在监听中会有contextInitialized(ServletContextEvent args)初始化⽅法,启动Web应⽤时,系统调⽤Listener的该⽅法,在这个⽅法中获得:
[html]
1. <span >ServletContext();</span>
context-param的值就是InitParameter("context-param的键");得到这个context-param的值之后,你就可以做⼀些操作了。
5. 举例:你可能想在项⽬启动之前就打开数据库,那么这⾥就可以在<context-param>中设置数据库的连接⽅式(驱动、url、user、password),在监听类中初始化数据库的连接。这个监听是⾃⼰写的⼀个类,除了初始化⽅法,它还有销毁⽅法,⽤于关闭应⽤前释放资源。⽐如:说数据库连接的关闭,此时,调⽤contextDestroyed(ServletContextEvent args),关闭Web应⽤时,系统调⽤Listener的该⽅法。
6. 接着,容器会读取<filter></filter>,根据指定的类路径来实例化过滤器。
7. 以上都是在WEB项⽬还没有完全启动起来的时候就已经完成了的⼯作。如果系统中有Servlet,则Servlet是在第⼀次发起请求的时候被实例化的,⽽且⼀般不会被容器销毁,它可以服务于多个⽤户的请求。所以,Servlet的初始化都要⽐上⾯提到的那⼏个要迟。
8. 总的来说,l的加载顺序是:<context-param>-><listener>-><filter>-><servlet>。其中,如果l中出现了相同的元素,则按照在配置⽂件中出现的先后顺序来加载。
9. 对于某类元素⽽⾔,与它们出现的顺序是有关的。以<filter>为例,l中当然可以定义多个<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>类似,此处不再赘述。
l标签详解
1. XML⽂档有效性检查
[html]
1. <span ><!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application
2.3//EN""java.sun/dtd/web-
app_2_3.dtd" ></span>
这段代码指定⽂件类型定义(DTD),可以通过它检查XML⽂档的有效性。下⾯显⽰的<!DOCTYPE>元素有⼏个特性,这些特性告诉我们关于DTD的信息:
1. web-app定义该⽂档(部署描述符,不是DTD⽂件)的根元素
2. PUBLIC意味着DTD⽂件可以被公开使⽤
3. -//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”意味着DTD由Sun Microsystems, Inc.维护。该信息也表⽰它描述的⽂档类型是DTD Web Application 2.3,⽽且
DTD是⽤英⽂书写的。
4. URL""表⽰D⽂件的位置。
2. <web-app></web-app>
部署描述符的根元素是<web-app>。DTD⽂件规定<web-app>元素的⼦元素的语法如下:
[html]
1. <span ><!ELEMENT web-app (icon?, display-name?, description?,distributable?, context-param*, filter*, filter-
mapping*,listener*, servlet*, servlet-mapping*, session-config?,mime-mapping*, welcome-file-list?,err
or-page*, taglib*, resource-env-ref*, resource-ref*,security-constraint*, login-config?, security-role*,env-entry*,ejb-ref*, ejb-local-ref*)> </span>
正如您所看到的,这个元素含有23个⼦元素,⽽且⼦元素都是可选的。问号(?)表⽰⼦元素是可选的,⽽且只能出现⼀次。星号(*)表⽰⼦元素可在部署描述符中出现零次或多次。有些⼦元素还可以有它们⾃⼰的⼦元素。l⽂件中<web-app>元素声明的是下⾯每个⼦元素的声明。下⾯讲述部署描述符中可能包含的所有⼦元素。
注意:在Servlet 2.3中,⼦元素必须按照DTD⽂件语法描述中指定的顺序出现。⽐如:如果部署描述符中的<web-app>元素有<servlet>和<servlet-mapping>两个⼦元素,则<servlet>⼦元素必须出现在<servlet-mapping>⼦元素之前。在Servlet2.4中,顺序并不重要。
3. <display-name></display-name>
<display-name>test-hwp-web-application</display-name>定义了web应⽤的名称,可以在中显⽰。如下所⽰:
4. <distributable/>
<distributable/>可以使⽤distributable元素来告诉servlet/JSP容器,Web容器中部署的应⽤程序适合在分布式环境下运⾏。
5. <context-param></context-param>
使⽤上下⽂初始化参数
1.
<!--****************************上下⽂初始化参数***************************-->
2.
<context-param>
3.
<param-name>webAppRootKey</param-name>
4.
<param-value&</param-value>
5.
</context-param>
6.
<!-- spring config -->
7.
<context-param>
8.
<param-name>contextConfigLocation</param-name>
9.
<param-value>/WEB-INF/spring-configuration/*.xml</param-value>
10.
</context-param>
5.1<context-param>解释:
<context-param>元素含有⼀对参数名和参数值,⽤作应⽤的Servlet上下⽂初始化参数,参数名在整个Web应⽤中必须是惟⼀的,在web应⽤的整个⽣命周期中上下⽂初始化参数都存在,任意的Servlet和jsp都可以随时随地访问它。<param-name>⼦元素包含有参数名,⽽<param-value>⼦元素包含的是参数值。作为选择,可⽤<description>⼦元素来描述参数。
5.2 什么情况下使⽤,为什么使⽤<context-param>:
⽐如:定义⼀个管理员email地址⽤来从程序发送错误,或者与你整个应⽤程序有关的其他设置。使⽤⾃⼰定义的设置⽂件需要额外的代码和管理;直接在你的程序中使⽤硬编码(Hard-coding)参数值会给你之后修改程序带来⿇烦,更困难的是,要根据不同的部署使⽤不同的设置;通过这种办法,可以让其他开发⼈员更容易到相关的参数,因为它是⼀个⽤于设置这种参数的标准位置。
5.3 Spring配置⽂件:
配置Spring,必须需要<listener>,⽽<context-param>可有可⽆,如果在l中不写<context-param>配置信息,默认的路径是/l,在WEB-INF ⽬录下创建的xml⽂件的名称必须是l。如果是要⾃定义⽂件名可以在l⾥加⼊contextConfigLocation这个context参数:在<param-value>
</param-value>⾥指定相应的xml⽂件名,如果有多个xml⽂件,可以写在⼀起并以“,”号分隔,⽐如在business-client⼯程中,我们采⽤了⾃定义配置⽅式,<context-param>配置如下:
1.
<!-- spring config -->
2.
<context-param>
3.
<param-name>contextConfigLocation</param-name>
4.
<param-value>/WEB-INF/spring-configuration/*.xml</param-value>
5.
</context-param>
6.
<listener>
7.
<listener-class>org.t.ContextLoaderListener</listener-class>
8.
</listener>
对应⼯程⽬录结构如下所⽰:
部署在同⼀容器中的多个Web项⽬,要配置不同的webAppRootKey,l⽂件中最好定义webAppRootKey参数,如果不定义,将会缺省为“”,如下:
1.
<!-- 应⽤路径 -->
2.
<context-param>
3.
<param-name>webAppRootKey</param-name>
4.
<param-value&</param-value>
5.
</context-param>
当然也不能重复,否则报类似下⾯的错误:
Web app root system property already set to different value: '' = [/home/user/tomcat/webapps/project1/] instead of [/home/user/tomcat/webapps/project2/] - Choose unique values for the 'webAppRootKey' context-param in l files!
意思是“”这个key已经指向了项⽬1,不可以再指向项⽬2。多个项⽬要对webAppRootKey
进⾏配置,我们⼯程主要是让log4j能将⽇志写到对应项⽬根⽬录下,⽐如:我们的项⽬的webAppRootKey为
1.
<!—business-client应⽤路径 -->
2.
<context-param>
3.
<param-name>webAppRootKey</param-name>
4.
<param-value> </param-value>
5.
</context-param>
6.
<!—public-base应⽤路径 -->
<context-param>
8.
<param-name>webAppRootKey</param-name>
9.
<param-value> </param-value>
10.
</context-param>
这样就不会出现冲突了。就可以在运⾏时动态地到项⽬路径,在log4j.properties配置⽂件中可以按下⾯的⽅式使⽤${}:
log4j.appender.file.File=${}/WEB-INF/logs/sample.log
就可以在运⾏时动态地出项⽬的路径。
5.4 多个配置⽂件交叉引⽤处理:
如果l中有contextConfigLocation参数指定的Spring配置⽂件,则会去加载相应的配置⽂件,⽽不会去加载/WEB-INF/下的l。但是如果没有指定的话,默认会去/WEB-INF/下加载l。
在⼀个团队使⽤Spring的实际项⽬中,应该需要多个Spring的配置⽂件,如何使⽤和交叉引⽤的问题:
多个配置⽂件可以在l⾥⽤空格分隔写⼊,如:
1.
<context-param>
2.
<param-name>contextConfigLocation </param-name>
3.
<param-value> l</param-value>
4.
<context-param>
多个配置⽂件⾥的交叉引⽤可以⽤ref的external或bean解决,例如:l
1.
<bean id="userService" class="domain.user.service.impl.UserServiceImpl">
2.
<property name="dbbean">
3.
<ref bean="dbBean"/>
4.
</property>
5.
</bean>
dbBean在l中。
5.5 在不同环境下如何获取:范例:
1.
<context-param>
2.
<param-name>param_name</param-name>
3.
<param-value>param_value</param-value>
4.
</context-param>
此所设定的参数,在JSP⽹页中可以使⽤下列⽅法来取得:
${initParam.param_name}
若在Servlet可以使⽤下列⽅法来获得:
String param_name=getServletContext().getInitParamter("param_name");
Servlet的ServletConfig对象拥有该Servlet的ServletContext的⼀个引⽤,所以可这样取得上下⽂初始化参数:getServletConfig().getServletContext().getInitParameter()也可以在Servlet中直接调⽤getServletContext().getInitParameter(),两者是等价的。
6. <session-config></session-config>
1.
<!-- Set timeout to 120 minutes -->
2.
<session-config>
3.
<session-timeout>120</session-timeout>
4.
</session-config>
<session-config> ⽤于设置容器的session参数,⽐如:<session-timeout> ⽤于指定http session的失效时间。默认时间设置在<jakarta>/l (30 minutes)。<session-timeout>⽤来指定默认的会话超时时间间隔,以分钟为单位。该元素值必须为整数。如果 session-timeout元素的值为零或负数,则表⽰会话将永远不会超时。
7. <listener></listener>
1.
<!--****************************配置*********************************-->
2.
<!-- Spring的log4j -->
3.
<listener>
4.
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
5.
</listener>
6.
<listener>
7.
<listener-class>org.t.ContextLoaderListener</listener-class>
</listener>
9.
<!-- 与CAS Single Sign Out Filter配合,注销登录信息 -->
10.
<listener>
11.
<listener-class&u.mcloud.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
12.
</listener>
7.1 Listener介绍:
<listener>为web应⽤程序定义,⽤来监听各种事件,⽐如:application和session事件,所有的按照相同的⽅式定义,功能取决去它们各⾃实现的接⼝,常⽤的Web事件接⼝有如下⼏个:
(1). ServletContextListener:⽤于监听Web应⽤的启动和关闭;
(2). ServletContextAttributeListener:⽤于监听ServletContext范围(application)内属性的改变;
(3). ServletRequestListener:⽤于监听⽤户的请求;
(4). ServletRequestAttributeListener:⽤于监听ServletRequest范围(request)内属性的改变;
(5). HttpSessionListener:⽤于监听⽤户session的开始和结束;
(6). HttpSessionAttributeListener:⽤于监听HttpSession范围(session)内属性的改变。
<listener>主要⽤于监听Web应⽤事件,其中有两个⽐较重要的WEB应⽤事件:应⽤的启动和停⽌(st
arting up or shutting down)和Session的创建和失效(created or destroyed)。应⽤启动事件发⽣在应⽤第⼀次被Servlet容器装载和启动的时候;停⽌事件发⽣在Web应⽤停⽌的时候。Session创建事件发⽣在每次⼀个新的session创建的时候,类似地Session失效事件发⽣在每次⼀个Session失效的时候。为了使⽤这些Web应⽤事件做些有⽤的事情,我们必须创建和使⽤⼀些特殊的“监听类”。它们是实现了以下两个接⼝中任何⼀个接⼝的简单java类:javax.servlet.ServletContextListener或javax.servlet.http.HttpSessionListener,如果想让你的类监听应⽤的启动和停⽌事件,你就得实现ServletContextListener接⼝;想让你的类去监听Session的创建和失效事件,那你就得实现HttpSessionListener接⼝。
7.2 Listener配置:
配置Listener只要向Web应⽤注册Listener实现类即可,⽆序配置参数之类的东西,因为Listener获取的是Web应⽤ServletContext(application)的配置参数。为Web应⽤配置Listener的两种⽅式:
(1). 使⽤@WebListener修饰Listener实现类即可。
(2). 在l⽂档中使⽤<listener>进⾏配置。
我们选择l这种配置⽅式,只有⼀个元素<listener-class>指定Listener的实现类,如下所⽰:
session如何设置和读取
1.
<listener>
2.
<listener-class>org.t.ContextLoaderListener</listener-class>
3.
</listener>
这⾥的<listener>⽤于Spring的加载,Spring加载可以利⽤ServletContextListener实现,也可以采⽤load-on-startup Servlet 实现,但是当<filter>需要⽤到bean时,但加载顺序是:先加载<filter>后加载<servlet>,则<filter>中初始化操作中的bean为null;所以,如果过滤器中要使⽤到bean,此时就可以根据加载顺序<listener> -> <filter> -> <servlet>,将spring的加载改成Listener的⽅式。
(1). 利⽤ServletContextListener实现:
1.
<servlet>
2.
<servlet-name>context</servlet-narne>
3.
<servlet-class>org.t.ContextLoaderServlet</servlet-class>
4.
<load-on-startup>1</load-on-startup>
5.
</servlet>
(2).采⽤load-on-startup Servlet 实现:
1.
<listener>
2.
<listener-class>org.t.ContextLoaderListener</listener-class>
3.
</listener>
我们选择了第⼆种⽅式,在J2EE⼯程中web服务器启动的时候最先调⽤l,上⾯这段配置的意思是加载spring的,其中ContextLoaderListener的作⽤就是启动Web 容器时,⾃动装配l的配置信息,执⾏它所实现的⽅法。
8. <filter></filter>
1.
<!--****************************过滤器配置*********************************-->
2.
<!-- 字符集过滤器 -->
3.
<filter>
4.
<filter-name>CharacterEncodingFilter</filter-name>
5.
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
6.
<init-param>
7.
<param-name>encoding</param-name>
8.
<param-value>UTF-8</param-value>
9.
</init-param>
10.
<init-param>
11.
<param-name>forceEncoding</param-name>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论