Listener用于监控Session内的对象,分别是HttpSessionBindingListener与HttpSessionActivationListener。它们的触发时机分别为:
- HttpSessionBindingListener:当对象被放到Session里时执行valueBound(HttpSessionBindingEvent event)方法。当对象被从Session里移除时执行valueUnbound(HttpSessionBingdingEvent event)方法。对象必须实现该Listener接口。
- HttpSessionActivationListener:服务器关闭时,会将Session里的内容保存到硬盘上,这个过程叫做钝化。服务器重新启动时,会将Session内容从硬盘上重新加载。当Session里的对象被钝化时会执行sessionWillPassivate(HttpSessionEvent event)方法。当对象被重新加载时执行sessionDidActivate(HttpSessionEvent event)。对象必须实现该Listener接口。
事例如下:
package linstener; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.Date; import java.util.Locale; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionEvent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class PersonInfo implements HttpSessionActivationListener,HttpSessionBindingListener,Serializable { /** * */ private static final long serialVersionUID = 1L; private Log log=LogFactory.getLog(this.getClass()); private String name; private Date dateCreated; @Override public void sessionDidActivate(HttpSessionEvent arg0) { //从硬盘恢复后被调用 HttpSession session =arg0.getSession(); log.info(this+"已经成功硬盘中加载。sessionid:" +session.getId()); } @Override public void sessionWillPassivate(HttpSessionEvent arg0) { //即将被钝化到硬盘时调用 HttpSession session=arg0.getSession(); log.info(this+"即将保存到硬盘。sessionid:"+session.getId()); } @Override public void valueBound(HttpSessionBindingEvent arg0) { //被放入session前调用 HttpSession session=arg0.getSession(); String name=arg0.getName(); log.info(this+"被绑定到session""+session.getId()+""的"+name+"属性上。"); this.setDateCreated(new Date()); } @Override public void valueUnbound(HttpSessionBindingEvent arg0) { //从session 中移除后调用 HttpSession session=arg0.getSession(); String name=arg0.getName(); log.info(this+"被从session""+session.getId()+""的"+name+"属性上移除。"); } public Date getDateCreated() { return dateCreated; } public void setDateCreated(Date dateCreated) { this.dateCreated = dateCreated; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "PersonInfo("+name+")"; } }
这两个Listener监听的是Session中的对象而非Session等,因此不需要在web.xml中声明。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <jsp:directive.page import="linstener.PersonInfo" /> <!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> <% PersonInfo personInfo =(PersonInfo)session.getAttribute("personInfo"); if(personInfo==null){ personInfo=new PersonInfo(); personInfo.setName("Alex Geng"); session.setAttribute("personInfo", personInfo); out.println("PersonInfo 对象不存在。已经成功新信件。sessionId:"+session.getId()); } else{ out.println("PersonInfo对象存在。无需新建。sessionId:"+session.getId()); } %> </body> </html>