1. 使用HttpSessionListener

public class OnlineUserListener implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent event) {
} public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
ServletContext application = session.getServletContext(); // 取得登录的用户名
String username = (String) session.getAttribute("username"); // 从在线列表中删除用户名
List onlineUserList = (List) application.getAttribute("onlineUserList");
onlineUserList.remove(username); System.out.println(username + "超时退出。");
} }

OnlineUserListener实现了HttpSessionListener定义的两个方法:sessionCreated()和sessionDestroyed()。这两个方法可以监听到当前应用中session的创建和销毁情况。我们这里只用到sessionDestroyed()在session销毁时进行操作就可以。

从HttpSessionEvent中获得即将销毁的session,得到session中的用户名,并从在线列表中删除。最后一句向console打印一条信息,提示操作成功,这只是为了调试用,正常运行时删除即可。

为了让监听器发挥作用,我们将它添加到web.xml中:

<listener>
<listener-class>anni.OnlineUserListener</listener-class>
</listener>

以下两种情况下就会发生sessionDestoryed(会话销毁)事件:

1.执行session.invalidate()方法时。

既然LogoutServlet.java中执行session.invalidate()时,会触发sessionDestory()从在线用户列表中清除当前用户,我们就不必在LogoutServlet.java中对在线列表进行操作了,所以LogoutServlet.java的内容现在是这样。

public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
// 销毁session
request.getSession().invalidate();
// 成功
response.sendRedirect("index.jsp");
}

2.如果用户长时间没有访问服务器,超过了会话最大超时时间,服务器就会自动销毁超时的session。

会话超时时间可以在web.xml中进行设置,为了容易看到超时效果,我们将超时时间设置为最小值。

<session-config>
<session-timeout>1</session-timeout>
</session-config>

时间单位是一分钟,并且只能是整数,如果是零或负数,那么会话就永远不会超时。

2. 使用HttpSessionBindingListener

HttpSessionBindingListener虽然叫做监听器,但使用方法与HttpSessionListener完全不同。我们实际看一下它是如何使用的。

我们的OnlineUserBindingListener实现了HttpSessionBindingListener接口,接口中共定义了两个方法:valueBound()和valueUnbound(),分别对应数据绑定,和取消绑定两个事件。

所谓对session进行数据绑定,就是调用session.setAttribute()把HttpSessionBindingListener保存进session中。我们在LoginServlet.java中进行这一步。

// 把用户名放入在线列表
session.setAttribute("onlineUserBindingListener", new OnlineUserBindingListener(username));

这就是HttpSessionBindingListener和HttpSessionListener之间的最大区别:HttpSessionListener只需要设置到web.xml中就可以监听整个应用中的所有session。HttpSessionBindingListener必须实例化后放入某一个session中,才可以进行监听。

从监听范围上比较,HttpSessionListener设置一次就可以监听所有session,HttpSessionBindingListener通常都是一对一的。

正是这种区别成就了HttpSessionBindingListener的优势,我们可以让每个listener对应一个username,这样就不需要每次再去session中读取username,进一步可以将所有操作在线列表的代码都移入listener,更容易维护。

valueBound()方法的代码如下:

public void valueBound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
ServletContext application = session.getServletContext(); // 把用户名放入在线列表
List onlineUserList = (List) application.getAttribute("onlineUserList");
// 第一次使用前,需要初始化
if (onlineUserList == null) {
onlineUserList = new ArrayList();
application.setAttribute("onlineUserList", onlineUserList);
}
onlineUserList.add(this.username);
}

username已经通过构造方法传递给listener,在数据绑定时,可以直接把它放入用户列表。

与之对应的valueUnbound()方法,代码如下:

public void valueUnbound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
ServletContext application = session.getServletContext(); // 从在线列表中删除用户名
List onlineUserList = (List) application.getAttribute("onlineUserList");
onlineUserList.remove(this.username); System.out.println(this.username + "退出。");
}

这里可以直接使用listener的username操作在线列表,不必再去担心session中是否存在username。

valueUnbound的触发条件是以下三种情况:

  1. 执行session.invalidate()时。

  2. session超时,自动销毁时。

  3. 执行session.setAttribute("onlineUserBindingListener", "其他对象");或session.removeAttribute("onlineUserBindingListener");将listener从session中删除时。

因此,只要不将listener从session中删除,就可以监听到session的销毁。

特别感谢http://www.mossle.com/docs/jsp/html/jsp-ch-08.html

HttpSessionListener和HttpSessionBindingListener监听session的销毁的更多相关文章

  1. SpringMVC拦截器实现:当用户访问网站资源时,监听session是否过期

    SpringMVC拦截器实现:当用户访问网站资源时,监听session是否过期 一.拦截器配置 <mvc:interceptors> <mvc:interceptor> < ...

  2. 【Java EE 学习 21 上】【其它类型的监听器】【使用HttpSessionActivationListener监听session的活化和钝化】

    一.ServletContextListener  Method Summary  void contextDestroyed(ServletContextEvent sce)           R ...

  3. Listener 监听Session内的对象

    Listener用于监控Session内的对象,分别是HttpSessionBindingListener与HttpSessionActivationListener.它们的触发时机分别为: Http ...

  4. 使用HttpSessionListener接口监听Session的创建和失效

    转自:http://uule.iteye.com/blog/824115 HttpSessionListener : Session创建事件发生在每次一个新的session创建的时候,类似地Sessi ...

  5. java web session监听销毁跳转

    1.了解如何使用HttpSessionListener监听session的销毁. 2.了解如何使用HttpSessionBindingListener监听session的销毁. 一. 使用HttpSe ...

  6. 用HttpSessionListener与HttpSessionBindingListener实现在线人数统计

    在线人数统计方面的实现,最初我的想法是,管理session,如果session销毁了就减少,如果登陆用户了就新增一个,但是如果是用户非法退出,如:未注销,关闭浏览器等,这个用户的session是管理不 ...

  7. [转]用HttpSessionListener与HttpSessionBindingListener实现在线人数统计

    原文链接:http://www.cnblogs.com/shencheng/archive/2011/01/07/1930227.html 下午比较闲(其实今天都很闲),想了一下在线人数统计方面的实现 ...

  8. Servlet之监听事件细究

    观察者三个模式: ServletContextListener:用于监听WEB 应用启动和销毁的事件,监听器类需要实现javax.servlet.ServletContextListener 接口. ...

  9. java中的监听事件

    java监听器实现的类 1.ServletContextListener:对servlet上下文的创建和销毁监听 2.ServletContextAttributeListener:监听servlet ...

随机推荐

  1. Portlet简述

    一.Portlet是什么? Portlet是基于java的web组件,由portlet容器管理,并由容器处理请求,生产动态内容.Portals使用portlets作为可插拔用户接口组件,提供信息系统的 ...

  2. Console.log,Window.alert,Document.write三者区别

    1.Console.log不会阻断程序继续进行,在控制台可以看到测试结果. 2.Window.alert弹出框会阻断程序运行,在弹出框可以看到测试结果. 3.Document.write不会阻断程序继 ...

  3. 转 Delphi Invalidate的用法

    1.Invalidate介绍 void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效.窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口 ...

  4. delphi override、overload、reintroduce的区别-0613.txt

    http://blog.csdn.net/honglixx/article/details/3624934 1.override overload reintroduce的中文叫法是什么? overr ...

  5. java基础内容

    此文作java语法基础的起始页,负责总结和目录引导 想我开始接触java语法也有比较长时间了(大概是2015年十月份),到现在(2016-10-25)为止还未系统的学习总结基础语法,亡羊补牢吧,回过头 ...

  6. iOS学习06C语言结构体

    1.结构体的概述 在C语言中,结构体(struct)指的是一种数据结构,是C语言中构造类型的其中之一. 在实际应用中,我们通常需要由不同类型的数据来构成一个整体,比如学生这个整体可以由姓名.年龄.身高 ...

  7. [转] linux 下查看一个进程运行路径的方法

    http://blog.csdn.net/brioxu/article/details/5104736 在linux下查看进程大家都会想到用 ps -ef|grep XXX ps -aux | hea ...

  8. Window.location

    1.location 对象 // 假设当前url是 http://localhost/rpc/plugin.php#hash?a=aaa&b=bbb alert(window.location ...

  9. ACM: 限时训练题解-Street Lamps-贪心-字符串【超水】

    Street Lamps   Bahosain is walking in a street of N blocks. Each block is either empty or has one la ...

  10. css切背景图片(background-position)

    给元素添加背景图片的方式有很多,个人总结的有: 用img插入图片: css3的方式手动绘图: 单独用background-image单独插入图片: 其中用background-image有两种方法,一 ...