1.了解如何使用HttpSessionListener监听session的销毁。
2.了解如何使用HttpSessionBindingListener监听session的销毁。
一. 使用HttpSessionListener
编写一个OnlineUserListener。

package anni;

import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionEvent; 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>

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

对应例子在08-01,为了验证OnlineUserListener是否能正常执行,我们可以登录两个用户,其中一个点击注销,另一个等待一分钟,然后可以在console中看到输出的信息。

二. 使用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("onlineUserListener", "其他对象");或session.removeAttribute("onlineUserListener");将listener从session中删除时。

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

java web session监听销毁跳转的更多相关文章

  1. java中的监听事件

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

  2. Session监听事件的处理

    设置Session监听  在web.xml文件中: <listener> <listener-class>cjq.login.listener.UpdateLogOutTime ...

  3. Session监听类HttpSessionListener介绍及在listener里取得request

    Session监听类HttpSessionListener介绍及在listener里取得request servlet-api.jar中提供了监听类HttpSessionListener,主要方法有两 ...

  4. java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用)

    java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用) 这是我关于会话技术的第二篇文章,对 Cookie有不了解的兄弟可以点击下方的Cookie跳转 Cookie链 ...

  5. jsp&servlet——session监听

    session监听,需要实现HttpSessionAttributeListener接口 attributeAdded:监听添加session attributeRemoved:监听删除session ...

  6. [置顶] java Gui 键盘监听事件

    简单写一个java Gui键盘监听事件,实现的效果就是按下键盘控制台输出你按下的键.比如:按下A控制台就输出A 效果如图: 以下把实现的效果分为几个步骤: 1.新建一个窗体类继承窗体: 2.给这个窗体 ...

  7. java实现网络监听

    Java实现网络监听 import java.net.*; import java.io.*; public class tcpServer { public static void main(Str ...

  8. java web session过期 跳转页面没有跳出frame的问题

    对于frame页面框架的java web项目,如果session过期执行跳转操作时,只在一个frame中(例如center frame)跳转到设置的login页面了,为了能直接跳转到最初的登录页面,就 ...

  9. java:(监听,上传,下载)

    1.监听: index.jsp: <%@ page language="java" import="java.util.*" pageEncoding=& ...

随机推荐

  1. Data Pump(数据抽取)介绍

    从10g开始,Oracle提供更高效的Data Pump(即expdp/impdp)来进行数据的导入和导出,老的exp/imp还可以用,但已经不建议使用.注意:expdp/impdp和exp/imp之 ...

  2. IIS用户权限备忘

    经常在网站部署到IIS遇到IIS帐户没有权限的问题,总是在看IIS Admin Service,但发现些帐户是有权限的. 其实针对相应的站点,应该看的是Application Pool的运行帐户,这个 ...

  3. docker加速器

    https://cr.console.aliyun.com/#/docker/booster 阿里云开发者账号注册后,获得一专属加速器地址. 转发自: http://www.imike.me/2016 ...

  4. debug,trace,release项目配置区别

    Debug模式是用来调试用的,它生成的执行文件中含有大量调试信息,所以很大: Release模式生成的执行文件消除了这些调试信息,可用来作为成品发布 Debug只在debug状态下会输出,Trace在 ...

  5. asp.net 程序,单击按钮时 同时实现打开页面并处理值

    来源:http://blog.csdn.net/nvhaixx/article/details/12430757 1)在网页中添加用于处理的客户端事件: <script language=&qu ...

  6. asp.net中HTML代码编码、解码与页面的重定向

    http://www.cnblogs.com/yjss/articles/2005894.html 1.编码(输出的字符串中包含HTML代码) Response.Write(Server.HtmlEn ...

  7. eclipse svn subclipse下载地址

    http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240 Eclipse 3.x Subclipse release ...

  8. SQL中的CASE的用法

    CASE在SQL语句中,很有点类似java等高级编程语言中的switch这样子的多分枝语句,但是有点不同的是,case后面接的是when,另外,when的后续分枝有点类似if后面接else.这个是我的 ...

  9. [转]String.getBytes()和new String()

    在Java中,String.getBytes(String decode)方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示,如 byte[] b_gbk = "中&q ...

  10. Python基础(三)——集合、有序 无序列表、函数、文件操作

    1.Set集合 class set(object): """ set() -> new empty set object set(iterable) -> n ...