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