一、监听域对象中属性的变更的监听器
域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。各个域属性监听器中的完整语法定义为:
public void attributeAdded(ServletContextAttributeEvent scae) public void attributeReplaced(HttpSessionBindingEvent hsbe) public void attributeRmoved(ServletRequestAttributeEvent srae)
public void attributeRemoved(ServletContextAttributeEvent scae) public void attributeRemoved (HttpSessionBindingEvent hsbe) public void attributeRemoved (ServletRequestAttributeEvent srae)
public void attributeReplaced(ServletContextAttributeEvent scae) public void attributeReplaced (HttpSessionBindingEvent hsbe) public void attributeReplaced (ServletRequestAttributeEvent srae)
package web.listener; import java.text.MessageFormat; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; /** * @ClassName: MyServletContextAttributeListener * @Description: ServletContext域对象中属性的变更的事件监听器 */ public class MyServletContextAttributeListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent scab) { String str =MessageFormat.format( "ServletContext域对象中添加了属性:{0},属性值是:{1}" ,scab.getName() ,scab.getValue()); System.out.println(str); } @Override public void attributeRemoved(ServletContextAttributeEvent scab) { String str =MessageFormat.format( "ServletContext域对象中删除属性:{0},属性值是:{1}" ,scab.getName() ,scab.getValue()); System.out.println(str); } @Override public void attributeReplaced(ServletContextAttributeEvent scab) { String str =MessageFormat.format( "ServletContext域对象中替换了属性:{0}的值" ,scab.getName()); System.out.println(str); } }
<listener> <description>MyServletContextAttributeListener监听器</description> <listener-class>me.gacl.web.listener.MyServletContextAttributeListener</listener-class> </listener>
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML> <html> <head> <title>ServletContextAttributeListener监听器测试</title> </head> <body> <% //往application域对象中添加属性 application.setAttribute("name", "西楚小羽"); //替换application域对象中name属性的值 application.setAttribute("name", "dhp"); //移除application域对象中name属性 application.removeAttribute("name"); %> </body> </html>
package web.listener; import java.text.MessageFormat; import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; public class MyRequestAndSessionAttributeListener implements HttpSessionAttributeListener, ServletRequestAttributeListener { @Override public void attributeAdded(ServletRequestAttributeEvent srae) { String str =MessageFormat.format( "ServletRequest域对象中添加了属性:{0},属性值是:{1}" ,srae.getName() ,srae.getValue()); System.out.println(str); } @Override public void attributeRemoved(ServletRequestAttributeEvent srae) { String str =MessageFormat.format( "ServletRequest域对象中删除属性:{0},属性值是:{1}" ,srae.getName() ,srae.getValue()); System.out.println(str); } @Override public void attributeReplaced(ServletRequestAttributeEvent srae) { String str =MessageFormat.format( "ServletRequest域对象中替换了属性:{0}的值" ,srae.getName()); System.out.println(str); } @Override public void attributeAdded(HttpSessionBindingEvent se) { String str =MessageFormat.format( "HttpSession域对象中添加了属性:{0},属性值是:{1}" ,se.getName() ,se.getValue()); System.out.println(str); } @Override public void attributeRemoved(HttpSessionBindingEvent se) { String str =MessageFormat.format( "HttpSession域对象中删除属性:{0},属性值是:{1}" ,se.getName() ,se.getValue()); System.out.println(str); } @Override public void attributeReplaced(HttpSessionBindingEvent se) { String str =MessageFormat.format( "HttpSession域对象中替换了属性:{0}的值" ,se.getName()); System.out.println(str); } }
<listener> <description>MyRequestAndSessionAttributeListener监听器</description> <listener-class>me.gacl.web.listener.MyRequestAndSessionAttributeListener</listener-class> </listener>
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML> <html> <head> <title>RequestAndSessionAttributeListener监听器测试</title> </head> <body> <% //往session域对象中添加属性 session.setAttribute("aa", "bb"); //替换session域对象中aa属性的值 session.setAttribute("aa", "xx"); //移除session域对象中aa属性 session.removeAttribute("aa"); //往request域对象中添加属性 request.setAttribute("aa", "bb"); //替换request域对象中aa属性的值 request.setAttribute("aa", "xx"); //移除request域对象中aa属性 request.removeAttribute("aa"); %> </body> </html>
package domain; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; /** * @ClassName: JavaBeanDemo1 * @Description: * 实现了HttpSessionBindingListener接口的 JavaBean对象可以感知自己被绑定到 Session中和从Session中删除的事件 当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的 void valueBound(HttpSessionBindingEvent event) 方法 当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法 * */ public class JavaBeanDemo1 implements HttpSessionBindingListener { private String name; @Override public void valueBound(HttpSessionBindingEvent event) { System.out.println(name+"被加到session中了"); } @Override public void valueUnbound(HttpSessionBindingEvent event) { System.out.println(name+"被session踢出来了"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public JavaBeanDemo1(String name) { this.name = name; } }
<%@ page language="java" pageEncoding="UTF-8"%> <%@page import=" me.gacl.domain.JavaBeanDemo1"%> <!DOCTYPE HTML> <html> <head> <title></title> </head> <body> <% //将javabean对象绑定到Session中 session.setAttribute("bean",new JavaBeanDemo1("西楚小羽")); //从Session中删除javabean对象 session.removeAttribute("bean"); %> </body> </html>
package domain.listener; import java.io.Serializable; import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionEvent; /** * 实现了HttpSessionActivationListener接口的 JavaBean 对象可以感知自己被活化和钝化的事件 * 活化:javabean对象和Session一起被反序列化(活化)到内存中。 * 钝化:javabean对象存在Session中,当服务器把session序列化到硬盘上时, * 如果Session中的javabean对象实现了Serializable接口 * 那么服务器会把session中的javabean对象一起序列化到硬盘上,javabean对象和Session一起被序列化到硬盘中的这个操作称之为钝化 * 如果Session中的javabean对象没有实现Serializable接口, * 那么服务器会先把Session中没有实现Serializable接口的javabean对象移除 然后再把Session序列化(钝化)到硬盘中 当绑定到 * HttpSession对象中的javabean对象将要随 HttpSession对象被钝化之前, web服务器调用该javabean对象对象的 void * sessionWillPassivate(HttpSessionEvent event)方法 这样javabean对象就可以知道自己将要和 * HttpSession对象一起被序列化(钝化)到硬盘中 当绑定到HttpSession对象中的javabean对象将要随 * HttpSession对象被活化之后, web服务器调用该javabean对象的 void * sessionDidActive(HttpSessionEvent event)方法 这样javabean对象就可以知道自己将要和 * HttpSession对象一起被反序列化(活化)回到内存中 * * @author denghp * */ public class JavaBeanDemo2 implements HttpSessionActivationListener, Serializable { /** * */ private static final long serialVersionUID = 6944571901073787572L; private String name; @Override public void sessionDidActivate(HttpSessionEvent se) { System.out.println(name + "和session一起从硬盘反序列化(活化)回到内存了,session的id是:" + se.getSession().getId()); } @Override public void sessionWillPassivate(HttpSessionEvent se) { System.out.println(name + "和session一起被序列化(钝化)到硬盘了,session的id是:" + se.getSession().getId()); } public String getName() { return name; } public void setName(String name) { this.name = name; } public JavaBeanDemo2(String name) { this.name = name; } }
context.xml文件的内容如下:
<Context> <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"> <Store className="org.apache.catalina.session.FileStore" directory="dhpSession"/> </Manager> </Context>
<%@page import="dhp.web.listener.JavaBeanDemo2"%> <%@ page language="java" contentType="text/html; charset=UTF-8" 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>Insert title here</title> </head> <body> 一访问JSP页面,HttpSession就创建了,创建好的Session的Id是:${pageContext.session.id} <hr/> <% session.setAttribute("bean",new JavaBeanDemo2("孤傲苍狼")); %> </body> </html>
我们可以在tomcat服务器的work\Catalina\localhost\JavaWeb_Listener_20140908\gacl文件夹下找到序列化到本地存储的session,如下图所示:
当再次访问这个Jsp页面时,服务器又会自动将已经钝化(序列化)到硬盘上HttpSession对象重新活化(反序列化)回到内存中。