监听器Listener
监听器Listener
一、监听器介绍
1.1监听器概念
监听器简单来说就是实现特定接口的普通的Java程序,这个程序专门用来监听另一个Java对象的方法调用或属性的改变,当被监听对象发生上述事件后,监听器的方法立刻执行。
二、JavaWeb中的监听器
2.1基本概念
JavaWeb中的监听器就是Servlet中的一种特殊的实现类,用于监听web应用程序中的ServletContext(application), HttpSession(session)和 ServletRequest(request)等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。
2.2 Servlet监听器的分类
监听的事件源分别为【ServletContext,HttpSession,ServletRequest】三个域中的对象。监听器按功能划分可分为三种类型:
- 监听域对象自身的创建和销毁事件监听器。
- 监听域对象中的属性的增加和删除的事件监听器。
- 监听绑定到Session域中的某个对象的状态的事件监听器。
监听域对象的创建和销毁
编写一个普通的java程序实现ServletContextListener,HttpSessionListener,ServletRequestListener三个接口,并重写创建和销毁方法。
范例:编写一个Listener类,监听ServletContext,HttpSession,ServletRequest对象的创建和销毁。
1、编写监听器
public class Listener implements ServletContextListener, HttpSessionListener, ServletRequestListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("监听ServletContext,创建ServletContext对象..."+sce); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("监听ServletContext,销毁ServletContext对象..."+sce); } @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("监听HttpSession,创建HttpSession对象..."+se); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("监听HttpSession,销毁HttpSession对象..."+se); } @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("监听ServletRequest,创建ServletRequest对象..."+sre); } @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("监听ServletRequest,销毁ServletRequest对象..."+sre); } }
2、在web.xml文件中注册监听器
<listener>
<listener-class>com.example.Listener.Listener</listener-class>
</listener>
监听对象属性的增加和删除
域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。
这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener,ServletRequestAttributeListener,这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件。
编写监听器
程序范例:编写一个java程序监听域对象属性的增加,删除和替换。
public class AttritubeListener implements ServletContextAttributeListener, ServletRequestAttributeListener, HttpSessionAttributeListener { @Override public void attributeAdded(ServletRequestAttributeEvent srae) { String name = srae.getName(); String value = (String) srae.getServletRequest().getAttribute("onepiece"); System.out.println("正在【增加】的属性名:"+name+"正在【增加】的属性值:"+value); } @Override public void attributeRemoved(ServletRequestAttributeEvent srae) { System.out.println("正在【删除】的属性名:"+srae.getName()); } @Override public void attributeReplaced(ServletRequestAttributeEvent srae) { String name = srae.getName(); String value = (String)srae.getServletRequest().getAttribute("onepiece"); System.out.println("正在【替换】的属性名:"+name+"正在【替换】的属性值"+value); } @Override public void attributeAdded(HttpSessionBindingEvent event) { String name = event.getName(); String value = (String) event.getSession().getAttribute("onepiece"); System.out.println("正在【增加】的属性名:"+name+"正在【增加】的属性值:"+value); } @Override public void attributeRemoved(HttpSessionBindingEvent event) { System.out.println("正在【删除】的属性名:"+event.getName()); } @Override public void attributeReplaced(HttpSessionBindingEvent event) { String name = event.getName(); String value = (String)event.getSession().getAttribute("onepiece"); System.out.println("正在【替换】的属性名:"+name+"正在【替换】的属性值"+value); } @Override public void attributeAdded(ServletContextAttributeEvent event) { String name = event.getName(); String value = (String) event.getServletContext().getAttribute("onepiece"); System.out.println("正在【增加】的属性名:"+name+"正在【增加】的属性值:"+value); } @Override public void attributeRemoved(ServletContextAttributeEvent event) { System.out.println("正在【删除】的属性名:"+event.getName()); } @Override public void attributeReplaced(ServletContextAttributeEvent event) { String name = event.getName(); String value = (String)event.getServletContext().getAttribute("onepiece"); System.out.println("正在【替换】的属性名:"+name+"正在【替换】的属性值"+value); } }
注册web.xml
<listener>
<listener-class>com.example.Listener.AttritubeListener</listener-class>
</listener>
编写attritube.jsp测试监听结果
<body> 监听request域对象属性 <ul/> <% request.setAttribute("onepiece","路飞"); request.setAttribute("onepiece","索隆"); request.removeAttribute("onepiece"); %> 监听session域对象属性 <ul/> <% session.setAttribute("onepiece","路飞"); session.setAttribute("onepiece","索隆"); session.removeAttribute("onepiece"); %> 监听application域对象属性 <ul/> <% application.setAttribute("onepiece","路飞"); application.setAttribute("onepiece","索隆"); application.removeAttribute("onepiece"); %> </body>
程序运行结果
感知Session绑定的事件监听器
保存在Session中的对象可以有多种状态:绑定到session中,从session中解绑;随session对象持久化到一个存储设备中(钝化到硬盘),随session对象从存储设备中恢复(活化到硬盘)
Servlet 规范中定义了两个特殊的监听器接口"【HttpSessionBindingListener和HttpSessionActivationListener"来帮助JavaBean 对象了解自己在Session域中的这些状态: ,实现这两个接口的类不需要 web.xml 文件中进行注册。】
程序范例:session的绑定解绑
/* 实现了HttpSessionBindingListener接口的 JavaBean对象可以感知自己被绑定到 Session中和从Session中删除的事件 当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的 void valueBound(HttpSessionBindingEvent event) 方法 当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法 */ public class JavaBeanListener implements HttpSessionBindingListener { String name; public JavaBeanListener(){}; public JavaBeanListener(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void valueBound(HttpSessionBindingEvent event) { System.out.println(name+"被加入到session中"); } @Override public void valueUnbound(HttpSessionBindingEvent event) { System.out.println(name+"被踢出session中"); } } <body> <% JavaBeanListener jbl = new JavaBeanListener("张三"); session.setAttribute("jbl",jbl); session.removeAttribute("jbl"); %> </body>
程序运行结果
session的钝化和活化
钝化和活化实质上就是序列化和反序列化,想要实现钝化和活化需要实现HttpSessionActivationListener接口,并配置context.xml文件。
当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被钝化(序列化)之前,web服务器调用该javabean对象的void sessionWillPassivate(HttpSessionEvent event) 方法。这样javabean对象就可以知道自己将要和HttpSession对象一起被序列化(钝化)到硬盘中.
当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被活化(反序列化)之后,web服务器调用该javabean对象的void sessionDidActive(HttpSessionEvent event)方法。这样javabean对象就可以知道自己将要和 HttpSession对象一起被反序列化(活化)回到内存中。
程序范例
public class JavaBeanListener2 implements HttpSessionActivationListener , Serializable { private int id; private String name; public JavaBeanListener2(){}; public JavaBeanListener2(int id,String name){ this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } //监听在钝化之前 @Override public void sessionDidActivate(HttpSessionEvent se) { System.out.println("JavaBeanListener2从硬盘中活化,Session的id是"+se.getSession().getId()); } //监听在活化之后 @Override public void sessionWillPassivate(HttpSessionEvent se) { System.out.println("JavaBeanListener2被钝化到硬盘中"+se.getSession().getId()); } }
context.xml文件的内容如下:
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="listener"/>
</Manager>
</Context>
在context.xml文件文件中配置了1分钟之后就将HttpSession对象钝化到本地硬盘的一个listener文件夹中
jsp测试代码:
<body> <% JavaBeanListener2 jbl2 = new JavaBeanListener2(); jbl2.setId(10); jbl2.setName("张三"); session.setAttribute("jbl2",jbl2); session.removeAttribute("jbl2"); %> </body>
访问这个jsp页面,服务器就会马上创建一个HttpSession对象,然后将实现了HttpSessionActivationListener接口的JavaBean对象绑定到session对象中,这个jsp页面在等待1分钟之后没有人再次访问,那么服务器就会自动将这个HttpSession对象钝化(序列化)到硬盘上。
程序运行结果
从硬盘中活化
<html>
<head>
<title>活化Session中的对象并取值</title>
</head>
<body>
ID:${sessionScope.jbl2.id}<br>
name:${sessionScope.jbl2.name}<br>
</body>
</html>





浙公网安备 33010602011771号