HttpSessionListener是对Session的一个监听,主要监听关于Session的两个事件,即初始化和销毁。
方法:
接口HttpSessionListener有两个方法,分别为:
VoidsessionCreated(HttpSessionEvent se):当session创建时会收到通知。
VoidsessionDestroyed(HttpSessionEvent se):当session销毁时也会收到通知。
Web.xml
<listener>
<listener-class>com.zte.init.SessionListener</listener-class>
</listener>
监听类:
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import SessionContext;
public class SessionListener implements HttpSessionListener
{
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent)
{
SessionContext.AddSession(httpSessionEvent.getSession());
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent)
{
HttpSession session = httpSessionEvent.getSession();
SessionContext.DelSession(session);
}
}
缓存用户Session key是sessionid value是Session:
import java.util.HashMap;
import javax.servlet.http.HttpSession;
public class SessionContext
{
private static HashMap<String, HttpSession> sessionMap = new HashMap<String, HttpSession>();
public static synchronized void AddSession(HttpSession session)
{
if (session != null)
{
sessionMap.put(session.getId(), session);
}
}
public static synchronized void DelSession(HttpSession session)
{
if (session != null)
{
sessionMap.remove(session.getId());
}
}
public static synchronized HttpSession getSession(String sessionId)
{
if (sessionId == null)
return null;
return sessionMap.get(sessionId);
}
}
根据sessionid获取Session对象:
HttpServletRequest session = ServletActionContext.getRequest();
String sessionId = session.getSession().getId();
HttpSession session = SessionContext.getSession(sessionId );
根据HttpSessionListener的特性,如果想在用户登录或者退出时做些什么,就可以设置session监听,例如:防止用户重复登录,统计用户在线数量,统计用户登录频率等等。
二、HttpSessionAttributeListener
HttpSessionAttributeListener是SessionAttribute的监听,当在会话对象中加入属性、移除属性或替换属性时,就会调用HttpSessionAttributeListener监听器。可以和HttpSessionBindingEvent合作着使用。
接口HttpSessionAttributeListener有3个方法:
public voidattributeAdded(HttpSessionBindingEvent se):在session中添加对象时触发此操作
public voidattributeRemoved(HttpSessionBindingEvent se):修改、删除session中添加对象时触发此操作
public voidattributeReplaced(HttpSessionBindingEvent se):在Session属性被重新设置时
实现示例:
web.xml
<listener>
<listener-class>com.zte.init.UserLoginListener</listener-class>
</listener>
监听器类:
public class UserLoginListener implements HttpSessionAttributeListener
{
@Override
public void attributeAdded(HttpSessionBindingEvent se)
{
}
@Override
public void attributeRemoved(HttpSessionBindingEvent se)
{
}
@Override
public void attributeReplaced(HttpSessionBindingEvent se)
{
}
}
OtherObject other = new OtherObject();
当有对象添加到session中时,session.setAttribute("object",other)触发attributeAdded事件,
当该对象从session移除时,session.removeAttribute("object")触发attriubteRemoved事件,
当该属性的值发生变化时, session.replaceAttribute("object",another)触发attributeRepalced事件。
注意:只要有对象保存到session中或从session中移除或改变属性的值都会触发相应事件,不论该对象是否实现了AttributeListener。
三、HttpSessionBindingListener
方法:
HttpSessionBindingListener有两种方法,
valueBound(HttpSessinBindingEvent) 实现BindingListener接口的对象被绑 定到session时触发valueBound事件
valueUnbount(HttpSessionBindingEvent) 解除绑定,既Session销毁时触发valueUnbound事件。
示例:
public class UserObject implements HttpSessionBindingListener{
public void valueBound(HttpSessionBindingEvent event){
System.out.println("触发绑定事件!");
}
public void valueUnbound(HttpSessionBindingEvent event){
System.out.println("解除和session的绑定");
}
}
它不需要配置xml文件,只是将实例化的HttpSessionBindingListener对象setAttribute到session里面就可以对HttpSessionBindingListener对象对象进行监听了,其实也就是对HttpSessionBindingListener对象所对应的session进行监听
所谓对session进行数据绑定,就是调用session.setAttribute()把HttpSessionBindingListener保存进session中
HttpSessionBindingListener和HttpSessionListener之间的最大区别:HttpSessionListener只需要设置到web.xml中就可以监听整个应用中的所有session。HttpSessionBindingListener必须实例化后放入某一个session中,才可以进行监听。
从监听范围上比较,HttpSessionListener设置一次就可以监听所有session,HttpSessionBindingListener通常都是一对一的。
正是这种区别成就了HttpSessionBindingListener的优势,我们可以让每个listener对应一个username,这样就不需要每次再去session中读取username,进一步可以将所有操作在线列表的代码都移入listener,更容易维护。
触发valueBound示例:
UsersOnlineCountListener uocl = new UsersOnlineCountListener();
uocl.setUid(obj.getUid());
session.setAttribute("uocl", uocl);//这个时候要触发valueBound方法了
valueUnbound的触发条件是以下三种情况:
1、执行session.invalidate()时。
2、session超时,自动销毁时。
3、执行session.setAttribute("onlineUserListener", "其他对象");或session.removeAttribute("onlineUserListener");将listener从session中删除时。
因此,只要不将listener从session中删除,就可以监听到session的销毁。