-
什么是监听器
监听器用于监听Web应用中某些对象的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当监听范围的对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。 -
监听器的常用场景
常用于统计网站在线人数、系统加载时进行信息初始化、统计网站的访问量等等。 -
监听器的分类
- 按监听的对象划分
ServletContext对象的监听器
HttpSession对象的监听器
ServletRequest对象的监听器 - 按监听的事件划分
对象自身的创建和销毁的监听器
对象中属性的创建和消除的监听器
session中的某个对象的状态变化的监听器
- 按监听的对象划分
-
监听器详解
-
ServletContext监听器
1.1> ServletContextListener监听ServletContext对象 1.2> ServletContextAttributeListener监听对ServletContext属性的操作,比如增加、删除、修改
-
HttpSession监听器
2.1> HttpSessionListener监听Session对象 2.2> HttpSessionAttributeListener监听Session中的属性操作 2.3> HttpSessionActivationListener监听HTTP会话的active和passivate情况,passivate是指非活动的session被写入持久设备(比如硬盘),active相反。 注意:HttpSessionActivationListener不需要web.xml配置文件 实现了HttpSessionActivationListener接口的 JavaBean 对象可以感知自己被活化和钝化的事件 活化:javabean对象和Session一起被反序列化(活化)到内存中(硬盘到内存); 钝化:javabean对象和Session一起序列化到硬盘中(内存到硬盘); javabean对象存在Session中,当服务器把session序列化到硬盘上时,如果Session中的javabean对象实现了Serializable接口 那么服务器会把session中的javabean对象一起序列化到硬盘上,javabean对象和Session一起被序列化到硬盘中的这个操作称之为钝化 如果Session中的javabean对象没有实现Serializable接口,那么服务器会先把Session中没有实现Serializable接口的javabean对象移除 然后再把Session序列化(钝化)到硬盘中; 当绑定到 HttpSession对象中的javabean对象将要随 HttpSession对象被钝化之前, web服务器调用该javabean对象的 sessionWillPassivate方法, 这样javabean对象就可以知道自己将要和 HttpSession对象一起被序列化(钝化)到硬盘中 当绑定到HttpSession对象中的javabean对象将要随 HttpSession对象被活化之后, web服务器调用该javabean对象的sessionDidActive方法, 这样javabean对象就可以知道自己将要和 HttpSession对象一起被反序列化(活化)回到内存中 2.4> HttpSessionBindingListener监听器:感知Session绑定的事件监听器 注意:HttpSessionBindingListener不需要web.xml配置文件 保存在Session域中的对象可以有多种状态: (1)绑定(session.setAttribute("bean",Object))到Session中; (2)从Session域中解除(session.removeAttribute("bean"))绑定; (3)随Session对象持久化到一个存储设备中; (4)随Session对象从一个存储设备中恢复; Servlet 规范中定义了两个特殊的监听器接口"HttpSessionBindingListener和HttpSessionActivationListener"来帮助JavaBean 对象了解自己在Session域中的这些状态: ,实现这两个接口的类不需要 web.xml 文件中进行注册。
-
ServletRequest监听器
3.1> ServletRequestListener监听Request对象
3.2> ServletRequestAttributeListener监听Requset中的属性操作
-
-
代码示例
-5.1.1> ServletContextListener
package cn.itcast.erp.listener.request;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
/**
*
* @ClassName: ServletRequestListener1
* @Description: TODO(ServletRequestListener监听Request对象)
* @author chenliming
* @date 2018年1月12日 上午10:52:24
*
*/
public class ServletRequestListener1 implements ServletRequestListener {
/**
* 该请求即将超出Web应用程序的范围。
* request将要销毁
*/
@Override
public void requestDestroyed(ServletRequestEvent event) {
System.out.println("request将要销毁");
}
/**
* 该请求即将进入Web应用程序的范围。
* request初始化
*/
@Override
public void requestInitialized(ServletRequestEvent event) {
System.out.println("request初始化");
}
}
web.xml配置代码:
<!-- ServletContext对象监听器 -->
<listener>
<listener-class>cn.itcast.erp.listener.servletContext.ServletContextListener1</listener-class>
</listener>
5.1.2> ServletContextAttributeListener
监听器类代码:
package cn.itcast.erp.listener.request;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
/**
*
* @ClassName: ServletRequestAttributeListener1
* @Description: TODO(ServletRequestAttributeListener监听Requset中的属性操作)
* @author chenliming
* @date 2018年1月12日 上午10:51:57
*
*/
public class ServletRequestAttributeListener1 implements ServletRequestAttributeListener {
/**
* 通知一个新的属性被添加到servlet请求。 在添加属性后调用。
*/
@Override
public void attributeAdded(ServletRequestAttributeEvent event) {
System.out.println("request添加属性后调用");
}
/**
* 通知现有的属性已经从servlet请求中删除。 在属性被删除后调用。
*/
@Override
public void attributeRemoved(ServletRequestAttributeEvent event) {
System.out.println("request删除属性后调用");
}
/**
* 通知servlet请求中已经替换了一个属性。 在属性被替换后调用。
*/
@Override
public void attributeReplaced(ServletRequestAttributeEvent event) {
System.out.println("request替换属性后调用");
String name = event.getName();
Object value = event.getValue();
System.out.println("request被替换的key:" + name + " ,替换前的value:" + value);
}
}
web.xml配置代码:
<!-- ServletContext属性的操作监听器 -->
<listener>
<listener-class>cn.itcast.erp.listener.servletContext.ServletContextAttributeListener1</listener-class>
</listener>
5.2.1>HttpSessionListener
监听类代码
package cn.itcast.erp.listener.session;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
*
* @ClassName: HttpSessionListener1
* @Description: TODO(HttpSessionListener监听Session对象创建和销毁)
* @author chenliming
* @date 2018年1月10日 上午10:48:54
*
*/
public class HttpSessionListener1 implements HttpSessionListener{
/**
* 通知会话已创建。
* session创建之后调用
*/
@Override
public void sessionCreated(HttpSessionEvent event) {
System.out.println("session创建之后");
HttpSession session = event.getSession();
}
/**
* 通知会话即将失效。
* session销毁之前调用
*/
@Override
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("session销毁之前");
HttpSession session = event.getSession();
}
}
web.xml配置
<!-- HttpSession对象监听器 -->
<listener>
<listener-class>cn.itcast.erp.listener.session.HttpSessionListener1</listener-class>
</listener>
5.2.2>HttpSessionAttributeListener
监听类代码
package cn.itcast.erp.listener.session;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class HttpSessionAttributeListener1 implements HttpSessionAttributeListener{
/**
* 通知某个属性已被添加到会话中。 在添加属性后调用。
*/
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.println("session添加属性后调用");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("被添加到session中的属性:" + "key=" + name + " ,value=" + value);
}
/**
* 通知某个属性已从会话中删除。 在属性被删除后调用。
*/
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
System.out.println("session删除属性后调用");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("被删除的session中的属性:" + "key=" + name + " ,value=" + value);
}
/**
* 在会话中通知属性已被替换。 在属性被替换后调用。
*/
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
System.out.println("session替换属性后调用");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("被替换的session中的属性:" + "key=" + name + " ,替换之前的value=" + value);
}
}
web.xml配置
<!-- HttpSession属性的操作监听器 -->
<listener>
<listener-class>cn.itcast.erp.listener.session.HttpSessionAttributeListener1</listener-class>
</listener>
5.2.3> HttpSessionActivationListener
监听器类代码(不需要配置web.xml):
package cn.itcast.erp.listener.session;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
/**
*
* @ClassName: HttpSessionActivationListener1
* @Description: TODO(实现了HttpSessionActivationListener接口的JavaBean被放入session中,session活化和钝化时会调用监听方法)
* @author chenliming
* @date 2018年1月11日 下午3:08:32
*
*/
public class HttpSessionActivationListener1 implements HttpSessionActivationListener {
/**
* 通知该会话即将被钝化。
* 当前javaBean绑定到session中钝化之前
*/
@Override
public void sessionWillPassivate(HttpSessionEvent event) {
System.out.println("session钝化之前");
HttpSession session = event.getSession();
}
/**
* 通知该会话刚刚被激活。
* 当前javaBean绑定到session中活化之后
*/
@Override
public void sessionDidActivate(HttpSessionEvent event) {
System.out.println("session活化之后");
HttpSession session = event.getSession();
}
}
配置Session对象的管理org.apache.catalina.session.PersistentManager方便序列化测试:
添加配置文件webapp/META-INF/context.xml
内容如下
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- Session对象的管理 -->
<!-- maxIdleSwap="1" (秒):n秒之后就将HttpSession对象钝化到本地硬盘的一个文件夹中 -->
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="e:/session/"></Store>
</Manager>
</Context>
测试页面JSP
<%@page import="cn.itcast.erp.listener.session.HttpSessionBindingListener1"%>
<%@page import="cn.itcast.erp.listener.session.HttpSessionActivationListener1"%>
<%@page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试HttpSessionActivationListener监听(session的活化和钝化)</title>
</head>
<body>
<%
//测试session活化和钝化监听器HttpSessionActivationListener
session.setAttribute("sessionActivation",new HttpSessionActivationListener1());
//测试session绑定和解绑监听器
session.setAttribute("sessionBind", new HttpSessionBindingListener1());
session.removeAttribute("sessionBind");
%>
<h1>session活化和钝化监听</h1>
</body>
</html>
5.2.4> HttpSessionBindingListener
监听器类代码(不需要配置web.xml):
package cn.itcast.erp.listener.session;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
/**
*
* @ClassName: HttpSessionBindingListener1
* @Description: TODO(HttpSessionBindingListener使对象在与会话绑定或解除绑定时得到通知。)
* @author chenliming
* @date 2018年1月12日 下午1:40:28
*
*/
public class HttpSessionBindingListener1 implements HttpSessionBindingListener {
/**
* 通知对象它正在被绑定到会话并标识会话。(还未绑定)
*/
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("当前对象正在绑定到session中,还未绑定");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("将要被绑定到session中的key值:" + name + "value值:" + value);
System.out.println("value值是否是当前对象:" + (value == this));//true
Object valueNow = session.getAttribute(name);
System.out.println("valueNow:" + valueNow);//null,还未绑定
}
/**
* 通知对象它正在从会话中解除绑定并标识会话。(还未解除绑定)
*/
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("当前对象它正在从会话中解除绑定");
HttpSession session = event.getSession();
String name = event.getName();
Object value = event.getValue();
System.out.println("将要解除绑定session中的key值:" + name + "value值:" + value);
System.out.println("value值是否是当前对象:" + (value == this));//true
Object valueNow = session.getAttribute(name);
System.out.println("valueNow:" + valueNow);//null,还未解除绑定
}
}
测试页面JSP
<%@page import="cn.itcast.erp.listener.session.HttpSessionBindingListener1"%>
<%@page import="cn.itcast.erp.listener.session.HttpSessionActivationListener1"%>
<%@page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试HttpSessionActivationListener监听(session的活化和钝化)</title>
</head>
<body>
<%
//测试session活化和钝化监听器HttpSessionActivationListener
session.setAttribute("sessionActivation",new HttpSessionActivationListener1());
//测试session绑定和解绑监听器
session.setAttribute("sessionBind", new HttpSessionBindingListener1());
session.removeAttribute("sessionBind");
%>
<h1>session活化和钝化监听</h1>
</body>
</html>
5.3.1> ServletRequestListener
监听器类代码:
package cn.itcast.erp.listener.request;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
/**
*
* @ClassName: ServletRequestListener1
* @Description: TODO(ServletRequestListener监听Request对象)
* @author chenliming
* @date 2018年1月12日 上午10:52:24
*
*/
public class ServletRequestListener1 implements ServletRequestListener {
/**
* 该请求即将超出Web应用程序的范围。
* request将要销毁
*/
@Override
public void requestDestroyed(ServletRequestEvent event) {
System.out.println("request将要销毁");
}
/**
* 该请求即将进入Web应用程序的范围。
* request初始化
*/
@Override
public void requestInitialized(ServletRequestEvent event) {
System.out.println("request初始化");
}
}
web.xml配置
<!-- ServletRequest对象监听器 -->
<listener>
<listener-class>cn.itcast.erp.listener.request.ServletRequestListener1</listener-class>
</listener>
5.3.2> ServletRequestAttributeListener
监听器类代码:
package cn.itcast.erp.listener.request;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
/**
*
* @ClassName: ServletRequestAttributeListener1
* @Description: TODO(ServletRequestAttributeListener监听Requset中的属性操作)
* @author chenliming
* @date 2018年1月12日 上午10:51:57
*
*/
public class ServletRequestAttributeListener1 implements ServletRequestAttributeListener {
/**
* 通知一个新的属性被添加到servlet请求。 在添加属性后调用。
*/
@Override
public void attributeAdded(ServletRequestAttributeEvent event) {
System.out.println("request添加属性后调用");
}
/**
* 通知现有的属性已经从servlet请求中删除。 在属性被删除后调用。
*/
@Override
public void attributeRemoved(ServletRequestAttributeEvent event) {
System.out.println("request删除属性后调用");
}
/**
* 通知servlet请求中已经替换了一个属性。 在属性被替换后调用。
*/
@Override
public void attributeReplaced(ServletRequestAttributeEvent event) {
System.out.println("request替换属性后调用");
String name = event.getName();
Object value = event.getValue();
System.out.println("request被替换的key:" + name + " ,替换前的value:" + value);
}
}
web.xml文件配置
<!-- ServletRequest属性的操作监听器 -->
<listener>
<listener-class>cn.itcast.erp.listener.request.ServletRequestAttributeListener1</listener-class>
</listener>
码云项目链接:
https://gitee.com/menghuanzhiming/erp/tree/master/erp1121/src/main/java/cn/itcast/erp
转载自:https://blog.youkuaiyun.com/menghuanzhiming/article/details/79042182