监听器概念
Servlet监听器是Servlet规范中定义的一种特殊类,用于监听ServletContext、HttpSession和ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中属性发生修改的事件。
监听对象:
- ServletContext:application,整个应用只存在一个
- HttpSession:session,针对每一个对话
- ServletRequest:request,针对每一个客户请求
监听内容:创建、销毁、属性改变事件
监听作用:可以在事件发生前、发生后进行一些处理,一般可以用来统计在线人数和在线用户、统计网站访问量、系统启动时初始化信息等。
监听器使用
创建步骤:
- 创建一个实现监听器接口的类
- 配置web.xml文件,注册监听器
<listener>
<listener-class>com.test.className</listener-class>
</listener>
监听器的启动顺序:按照web.xml的配置顺序来启动
加载顺序:监听器>过滤器>Servlet
监听器的分类
按照监听的对象划分
- 用于监听应用程序环境对象(ServletContext)的事件监听器,实现ServletContextListener、ServletContextAttributeListener接口
- 用于监听用户会话对象(HttpSeesion)的事件监听器,实现HttpSessionListener、HttpSessionAttributeListener接口
- 用于监听请求消息对象(ServletRequest)的事件监听器,实现ServletRequestListener、ServletRequestAttributeListener接口
按照监听事件划分
监听域对象自身的创建和销毁的事件监听器
根据监听对象不同分别实现ServletContextListener、HttpSessionListener、ServletRequestListener接口。
1、ServletContext的创建和销毁:contextInitialized方法和contextDestroyed方法
//监听应用程序环境对象(ServletContext)的事件监听器
ServletContext sc = this.getServletContext(); //创建context
sc.setAttribute("Application","Application新增数据"); //新增Application
sc.setAttribute("Application","Application更新数据"); //新增Application
sc.removeAttribute("Application"); //新增Application
主要用途:作为定时器、加载全局属性对象、创建全局数据库连接、加载缓存信息等
生命周期:服务器启动>服务器关闭
在web.xml中可以配置项目初始化信息,在contextInitialized方法中进行启动
<context-param>
<param-name>属性名</param-name>
<param-value>属性值</param-value>
</context-param>
/*
* 监听Application对象的创建的销毁
* */
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//监听Application的创建
//获取web.xml中配置的属性
//String value=servletContextEvent.getServletContext().getInitParameter("属性名");
System.out.println("MyListener.contextInitialized(Application创建成功)");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//监听Application的销毁
System.out.println("MyListener.contextDestroyed(Application销毁成功)");
}
/*
* 监听Application作用域数据的变更
* */
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
//监听Application作用域数据的新增
System.out.println("MyListener.attributeAdded(Application新增一条数据)"+servletContextAttributeEvent.getName()
+":"+servletContextAttributeEvent.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
//监听Application作用域数据的删除
System.out.println("MyListener.attributeRemoved(Application删除一条数据)"+servletContextAttributeEvent.getName()
+":"+servletContextAttributeEvent.getValue());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
//监听Application作用域数据的更新
System.out.println("MyListener.attributeReplaced(Application更新一条数据)"+servletContextAttributeEvent.getName()
+":"+servletContextAttributeEvent.getValue());
}
2、HttpSession的创建和销毁:sessionCreated和sessionDestroyed方法
//监听用户会话对象(HttpSession)的事件监听器
HttpSession hs = req.getSession(); //创建session
hs.setAttribute("Session","Session新增数据"); //新增session
hs.setAttribute("Session","Session更新数据"); //更新session
hs.removeAttribute("Session"); //更新session
hs.invalidate(); //销毁session
主要用途:统计在线人数、记录访问日志等
生命周期:创建session>销毁session
web.xml配置session超时参数,单位:分,session超时的时间并不是精确的
<session-config>
<session-timeout>10</session-timeout>
</session-config>
/*
* 监听Session对象的创建的销毁
* */
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
//监听session的创建
System.out.println("MyListener.sessionCreated(Session创建成功)");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
//监听session的销毁
System.out.println("MyListener.sessionDestroyed(Session销毁成功)");
}
/*
* 监听Session作用域数据的变更
* */
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
//监听Session作用域数据的新增
System.out.println("MyListener.attributeAdded(Session增加一条数据)"+httpSessionBindingEvent.getName()
+":"+httpSessionBindingEvent.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
//监听Session作用域数据的删除
System.out.println("MyListener.attributeRemoved(Session更新一条数据)"+httpSessionBindingEvent.getName()
+":"+httpSessionBindingEvent.getValue());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
//监听Session作用域数据的更新
System.out.println("MyListener.attributeReplaced(Session删除一条数据)"+httpSessionBindingEvent.getName()
+":"+httpSessionBindingEvent.getValue());
}
3、ServletRequest的创建和销毁:requestInitialized和requestDestroyed方法
//监听请求消息对象(ServletRequest)的事件监听器
req.setAttribute("Request","Request新增数据"); //新增request
req.setAttribute("Request","Request更新数据"); //更新request
req.removeAttribute("Request"); //删除request
主要用途:读取request参数,记录访问历史
生命周期:请求开始>请求结束
/*
* 监听Request对象的创建和销毁
* */
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
//创建时调用
System.out.println("MyListener.requestDestroyed(Request销毁成功)");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
//销毁时调用
System.out.println("MyListener.requestInitialized(Request创建成功)");
}
/*
* 监听Request作用域数据的变更
* */
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
//监听request作用域数据的添加
System.out.println("MyListener.attributeAdded(Request增加一条数据)"+servletRequestAttributeEvent.getName()
+":"+servletRequestAttributeEvent.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
//监听request作用域数据的删除
System.out.println("MyListener.attributeRemoved(Request删除一条数据)"+servletRequestAttributeEvent.getName()
+":"+servletRequestAttributeEvent.getValue());
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
//监听request作用域数据的变更
System.out.println("MyListener.attributeReplaced(Request变更一条数据)"+servletRequestAttributeEvent.getName()
+":"+servletRequestAttributeEvent.getValue());
}
监听域对象中的属性的增加和删除的事件监听器
根据监听对象不同分别实现ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener接口。
实现方法:attributeAdded、attributeRemoved、attributeReplaced
获取监听数据的键:servletRequestAttributeEvent.getName()
获取监听数据的值:servletRequestAttributeEvent.getValue()
监听绑定到HttpSeesion域中的某个对象的状态的事件监听器(创建普通JavaBean)
HttpSession中的对象状态:
绑定→解除绑定;钝化→活化
实现接口及方法:
HttpSessionBindingListener接口(valueBound和valueUnbound方法)、HttpSessionActivationListener接口(sessionWillPassivate和sessionDidActivate方法)
注意:
- 要实现钝化和活化必须实现Serializable接口
- 不需要在web.xml中注册
- 绑定:通过setAttribute保存到session对象当中
- 解除绑定:通过removeAttribue去除
- 钝化:将session对象持久化到存储设备上
- 活化:将session对象从存储设备上进行恢复
session钝化机制:
- 把服务器不常使用的session对象暂时序列化到系统文件或者是数据库中,当使用时反序列化到内存中,整个过程由服务器自动完成;
- session的钝化机制由SessionManager管理,创建一个普通的JavaBean绑定和接触需要实现HttpSessionBindingListener接口
网站登录计数
public class Listener implements HttpSessionListener,ServletContextListener{
/**
* session被销毁时人数自增
* @param httpSessionEvent
*/
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
//获取ServletContext对象
ServletContext sc = httpSessionEvent.getSession().getServletContext();
//获取在线统计人数的变量
int count = (int) sc.getAttribute("count");
sc.setAttribute("count",++count);
}
/**
* session被销毁时人数自减
* @param httpSessionEvent
*/
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext sc = httpSessionEvent.getSession().getServletContext();
int count = (int) sc.getAttribute("count");
sc.setAttribute("count",--count);
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//获取Application
ServletContext sc = servletContextEvent.getServletContext();
//在Application对象存储变量用来统计在线人数
sc.setAttribute("count",0);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}