??xml version="1.0" encoding="utf-8" standalone="yes"?>
?/span> Servlet2.3 规范中添加了(jin)一些监?/span> web 应用中重要事件的能力。这功能可以让我们Ҏ(gu)事g的状态更有效的对资源q行理和自动化q行。这部分描述?/span> servlet 的事件监听,包含以下部分Q?/span>
1Q?/font> (tng) 事g的分cd Listener 接口
2Q?/font> (tng) 典型的事件监听过E?/font>
3Q?/font> (tng) 事g监听的声明和调用
4Q?/font> (tng) 事g监听~码和发布向?/font>
5Q?/font> (tng) 事g监听的方法和相关的类
事g的分cd Listener 接口
Servlet 事g有两个别:(x)
1Q?/font> (tng) Application U别事g
包含着q行应用E序的虚拟机U别的相兌源和状态,卛_ servlet ?/span> Context 对象相关?/span>
2Q?/font> (tng) Session U别的事?/font>
包含着一个单一用户?/span> session 的一pdh的相兌源和状态,?/span> Http ?/span> Session 对象?/span>
在上面两个别的事gQ又可分别分ZU:(x)
1Q?/font> (tng) 生命周期的改?/font>
2Q?/font> (tng) 属性的改变
你可以ؓ(f)上面四种事g创徏一个或多个监听cR一个单一的监听类可以监视多种事g?/font>
创徏一个事件类可以?/span> javax.servlet 包或 javax.servlet.http 包中实现合适的接口。下表中列出?jin)四U事件相关的接口?/span>
事gU类 |
事g描述 |
接口 |
Context 生命周期的改?/span> |
context 的徏立和卛_关闭 context |
Javax.servlet.ServletContextListener |
Context 属性值的改变 |
dQ删除,修改 context 的属性?/span> |
Javax..servlet.ServletContextAttributeListener |
Session 生命周期的改?/span> |
Session 的创建,注销Q超?/span> |
Javax.servlet.http.HttpSessionListener |
Session 属性值的改变 |
dQ删除,修改 session 的属性?/span> |
Javax.servlet.htpp.HttpSessionAttributeListener |
典型的事件监听过E?/font>
考虑一?/span> web 应用是由一l访问数据库?/span> servlet l成的。一个典型的事g监听机制是这L(fng)Q创Z?/span> context 生命周期的事件来理数据库连接,q个监听器可以有如下的功能:(x)
1Q?/font> (tng) q个监听器监视着应用E序的启?/font>
2Q?/font> (tng) q个应用E序写入日志到数据库中ƈ且把q接对象存储?/span> context ?/span>
3Q?/font> (tng) Servelt 使用q接对象来执?/span> SQL
4Q?/font> (tng) 监听器监听应用程序的卛_关闭
5Q?/font> (tng) 在关闭应用程序之前,先关闭连接对?/font>
事g监听的声明和调用
事g监听的声明在应用E序?/span> web.xml 里,?/span> <listener> 元素Q该元素?/span> <web-app> 的子元素。每个监听器都对应一?/span> <listener> Q有一?/span> <listener-class> 子元素用来指定对应的cd。在每种事g中,你需要指定你惌用的序?/span>
在应用程序启动之后,q且在第一ơ请求之前, servlet 容器?x)创建ƈ注册每个监听cȝ实例。每U事Ӟ监听器是按照他们声明的顺序来注册的。然后,当应用程序开始运行,每种事g监听器安装他们的序调用。在最后一ơ请求之前,所有的监听器都保持zd状态?/span>
一旦应用程序关闭, session 事g首先发生Q以他们声明的顺序相反。然?/span> context 事g发生也是以声明的序相反?/span>
下面是一个例子:(x)
<web-app>
(tng) (tng) <display-name>MyListeningApplication</display-name>
(tng) (tng) <listener>
(tng) (tng) (tng) (tng) (tng) <listener-class>com.acme.MyConnectionManager</listenerclass>
(tng) (tng) </listener>
(tng) (tng) <listener>
(tng) (tng) (tng) (tng) (tng) <listener-class>com.acme.MyLoggingModule</listener-class>
(tng) (tng) </listener>
(tng) (tng) <servlet>
(tng) (tng) (tng) (tng) (tng) <display-name>RegistrationServlet</display-name>
(tng) (tng) (tng) (tng) (tng) ...
(tng) (tng) </servlet>
</web-app>
假设 MyConnectionMnanager ?/span> MyLoggingModule 都是实现 ServletContextListener 接口Q?/span> MyLoggingModule 也是实现?/span> HttpSessionListener 接口?/span>
当应用程序运行,两个监听器都?x)监?/span> context 生命周期事gQ?/span> MyLoggingModule 监听器还?sh)(x)监?/span> session 生命周期。在 context 生命周期中, MyConnectionMananger ?x)首先开始监听,因ؓ(f)它声明在前面?/span>
事g监听器的~码和发布指?/font>
h意事件监听器cȝ以下规则和指南:(x)
l (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 在多U程的应用程序中Q属性可能同时改变。这是不需?/span> Servlet 容器来同步结果――在q种情况下监听类本n负责保持数据的完整性?/span>
l (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 每个监听c都必须有一?/span> public 的零参数的构造函数?/span>
l (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 每个监听cL件必L包到 WAR 文gQ也可以是在 /WEB-INF/classes 或是包含?/span> /WEB-INF/lib 下的 JAR 文g中?/span>
注意Q在分布式的环境中,事g监听cȝ作用域是包含q个部v描述文g的虚拟机。不需要分布式?/span> Web 容器来传?/span> servlet ?/span> context 事g或是 session 事g到其他的虚拟机。这个在 Sun Microsystem ?/span> Java Servlet 规范Q?/span> 2.3 版本?/span>
事g监听器的Ҏ(gu)和相关的c?/font>
q部分列Z(jin)事g监听器的Ҏ(gu)Q当 servlet ?/span> context 事g或是 servlet ?/span> session 事g发生Ӟ容器会(x)调用他们。这些方法的输入的事件对象的cd不一P因此一下讨Z件类和他们的Ҏ(gu)?/span>
ServletContextListener Ҏ(gu)Q?/span> ServletContextEvent c?/span>
ServletContextListener 接口规范以下的方法:(x)
(tng) (tng) (tng) (tng) (tng) (tng) void contextInitialized(ServletContextEvent sce)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) servlet 容器调用q个Ҏ(gu)来通知监听器, servlet ?/span> context 已经建立q且应用E序准备处理h?/span>
(tng) (tng) (tng) (tng) (tng) (tng) void contextDestory(ServletContextEvent sce)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) servlet 容器调用q个Ҏ(gu)来通知监听器应用程序即关闭?/span>
Servlet 容器创徏一?/span> java.servlet.ServletContextEvent 对象作ؓ(f)调用 ServletContextListener Ҏ(gu)的输入?/span> ServletContextEvent cd含以下方法,你的监听器可以调?/span>
ServletContext getServletContext()
用这个方法返回已创徏的或是将要销毁的 servlet context 对象Q从中你可以得到你想要的信息。(未完待箋(hu)Q?/span>
(tng)
(tng)
(tng)
(tng)
(tng)
(tng)