文章目录
11.1、简介
- 应用程序事件功能使web应用程序开发人员可以更好地控制ServletContext和HttpSession和ServletRequest的生命周期,实现更好的代码分解,并提高管理web应用程序使用的资源的效率。
11.2、事件监听器
- 应用程序事件监听器是实现一个或多个事件监听器接口的类,在部署Web应用程序时候,将实例化他们并将其注册在web容器中,他们由WAR中的开发人员提供
- Servlet事件监听器支持ServletContext,HttpSession和ServletRequest对象中状态更改的事件通知。Servlet上下文监听器用于管理应用程序在JVM级别上持有的资源或状态,HTTP会话监听器用于管理与同一客户端或同一用户向Web应用程序发出的一系列请求相关的状态或资源,servlet请求监听器用于管理的Servlet请求生命周期中的状态,异步监听器用于管理异步事件,例如超时和异步处理完成。
- 可能有多个监听器类监听每种事件类型,并且开发人员可以指定容器为每种事件类型调用监听器bean的顺序。
11.2.1、事件类型和监听器接口
-
Servlet 上下文事件
-
事件类型 描述 监听接口 生命周期 servlet上下文刚刚创建,可用于服务第一个请求,或者servlet上下文即将关闭 javax.servlet.ServletContextListener 改变属性 servlet上下文属性添加、移除、或替换时候 javax.servlet.ServletContextAttributeListener
-
-
HttpSession 事件
-
事件类型 描述 监听接口 生命周期 一个HttpSession被创建、验证无效或超时的时候 javax.servlet.http.HttpSessionListener 属性变更 HttpSession属性被添加、移除、替换 javax.servlet.http.HttpSessionAttriuteListener 会话id变更 HttpSession的id变更时候 javax.servlet.http.HttpSessionListener 会话迁移 HttpSession 已经被激活或休眠 javax.servlet.http.HttpSessionActivationListener 对象绑定 对象绑定或解绑于HttpSession javax.servlet.http.HttpSessionBindingListener
-
-
Servlet请求事件
-
事件类型 描述 监听接口 生命周期 一个servlet请求被web组件处理时候 javax.servlet.ServletRequestListener 属性变更 ServletReques的t属性添加、异常,替换 javax.servlet.ServletRequestAttributeListener 异步事件 异步处理超时、连接终止或完成 javax.servlet.AsyncListener
-
11.2.2、一个监听器使用例子
- 为了说明事件方案的用法,请考虑一个简单的web应用程序,其中包含许多使用数据库的servlet,开发人员提供了一个Servlet上下文监听器类,用于管理数据库连接
- 当应用程序启动时,将通知监听器类。该应用程序登录到数据库,并将连接存储在servlet上下文中。
- 在web应用程序中进行活动期间,应用程序中的servlet根据需要访问连接
- 关闭Web服务器或从web服务器中删除应用程序时,将通知监听器类并关闭数据库连接。
11.3、监听器类配置
11.3.1、提供监听器类
- web应用程序的开发人员提供了监听器类,这些监听器类在javax.servlet API中实现了一个或多个监听器接口,每个监听器类都必须具有不带参数的公共构造函数。监听器被打包到WAR中,或者位于WEB-INF /classes文件目录下,或者位于WEB-INF /lib目录中的JAR内部
11.3.2、部署声明
- 监听器是使用监听器元素 在web应用程序部署描述符中声明的,它们按照被调用的顺序按类名列出,与其他监听器不同,异步只能以编程方式(使用ServletRequest)注册AsyncListener类监听器
11.3.3、监听器注册
- web容器创建每个监听器类的实例,并在应用程序处理第一个请求之前将其注册以用于事件通知,web容器根据监听器实例实现的接口以及它们在部署描述符中出现的顺序来注册监听器实例。在web应用程序执行期间,给定事件的监听器通常以其注册顺序调用,但是也有一些例外。例如,以相反的顺序调用HttpSessionListener.destroy. 有关详细信息,请参见第8.2.3节,从web.xml, web-fragment.xml和注释组装描述符
11.3.4、在关闭时候通知
- 在应用程序关闭时,将以与声明相反的顺序通知监听器,并先向会话监听器发出通知,然后再向上下文监听器发出通知。必须在向上下文监听器通知应用程序关闭之前,向会话监听器通知会话无效。
11.4、部署描述文件示例
-
下面例子注册两个servlet上下文生命周期监听器和HttpSession监听器
-
com.acme.MyConnectionManager和com.acme.MyLoggingModule 两个都实现了javax.servlet.ServletContextListener, 其中com.acme.MyLoggingModule 额外实现javax.servlet.http.HttpSessionListener, 也就说,开发者想要com.acme.MyConnectionManager在com.acme.MyLoggingModule之前通知。以下是部署文件描述符
-
<web-app> <display-name>MyListeningApplication</display-name> <listener> <listener-class>com.acme.MyConnectionManager</listener-class> </listener> <listener> <listener-class>com.acme.MyLoggingModule</listener-class> </listener> <servlet> <display-name>RegistrationServlet</display-name> ... 省略 </servlet> </web-app>
11.5、监听器实例和线程
- 在开始执行对应用程序的第一个请求之前,需要使用容器来完成Web应用程序中监听器类的实例化,容器必须维护对每个监听器实例的引用,直到为web应用程序提供了最后一个请求。
- ServletContext和HttpSession对象属性更改可能同时发生。 容器不需要将结果同步通知到属性监听器类,维护状态的监听器类负责数据的完整性,并应明确处理此情况。
11.6、监听器异常
- 监听器内部的应用程序代码在操作过程中可能会引发异常,一些监听器通知发生在应用程序中另一个组件调用树下,这样的一个示例设置
11.7、分发的容器
- 在分布式web容器中,HttpSession实例的作用域为特定的JVM服务会话请求,而ServletContext对象的作用域为Web容器的JVM,不需要分布式容器将servlet上下文事件或HttpSession事件传播到其他JVM。每个JVM的每个部署描述符声明的监听器类实例的作用域为一个。
11.8、session 事件
- 监听器为开发人员提供了一种在web应用程序中跟踪会话的方法,在跟踪会话中,了解会话是否因容器超时或由于应用程序中的web组件称为invalidate方法而超时而变得非常有用。可以使用监听器和HttpSession API方法间接确定区别。