当前位置: 首页 > 图文教程 > 网络编程 > JSP > 再论Session事件的捕获

JSP
Hibernate save() saveorupdate()的用法
hibernate更新数据方法小结
jsp 复选框使用方法
JSP单选按钮验证、下拉框验证、复选框验证实现代码
jsp Hibernate批量更新和批量删除处理代码
JSP彩色验证码的实例代码
[J2SE]Java中3DES加密解密调用示例
【算法】扑克发牌算法实现
java易懂易用的MD5加密(可直接运行) (1)
java 易懂易用的MD5加密(可直接运行)(2)
java 截取字符串(判断汉字)
java 中文字符串数组按照音序排列
JAVA 18位身份证号码校验码的算法
jsp JFreeChart使用心得与例子
Hibernate 查询方式总结
java struts常见错误以及原因分析
Java 获取URL的内容
JAVA (Jsp)利用Google的Translate开发API的代码
java SOAPHEADER的web service
JSP与JS交互问题 值传递

JSP 中的 再论Session事件的捕获


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-03   浏览: 66 ::
收藏到网摘: n/a

    最近又有网友问到,如何用Session实现在线统计的功能,其实只要对Servlet规范详细了解一下,明白其基本原理,编写一个类似的功能并不是一件很复杂的事情。我以前的一篇文章,最初也是发表在JavaResearch上的(http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=2164),不过可能源码没有全部给出,只给出了最重点的源码,所以还是有很多网友给我发信索取全部源码。因为那个项目是以前做的,所以我手头上也没有原来的代码了,所以可能有的网友的要求就满足不了了,在这里一并致歉。

    第一篇文章是基于Servlet2.2规范编写的,那时候没有HttpSessionListener,鉴于目前绝大多数的应用服务器都支持2.3的规范,所以为了回应网友的提问,特地又基于2.3以上的规范编写了一个简单的测试例子。
这个例子的最主要功能就是提供在线用户列表显示(既然用户列表都可以显示了,那人数统计自然也不在话下了)。

    在给出代码之前,先简单说一下监听器的常识。

    HttpSessionListener:网友rdfei 在他的文章(http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=18541)中也已经进行了比较详细的描述,这是2.3以上规范所提供的一个新功能,也就是可以定义监听器监听HttpSession对象的创建和销毁。每当有新的用户访问网站,应用服务器会创建一个HttpSession对象,每当Session超时,应用服务器则会销毁这个对象。
HttpSessionBindingListener:每当往Session中存入一个对象(setAttribute)或从Session中删除一个对象的时候,如果这个对象实现了此监听器接口,应用服务器将会自动调用接口相应的方法。

    需要注意的一点就是,在sessionDestroyed方法和valueUnbound方法中,你可以得到HttpSession对象的实例,但是其getAttribute方法不再可用,也就是在这两个方法中,你不能再次得到存入session中的对象。

基于以上这些粗浅的认识,再简单介绍一下我提供的测试例子的情况:

测试例子总共包含如下文件:
OnlineUserListener.java:它实现了HttpSessionListener接口
OnlineUsers.java:它包含了所有正在访问网站的用户信息,为了方便起见,它也实现了HttpSessionBindingListener接口(实际中你最好把他们分开吧)
User.java:这是用户的信息
test.jsp:为了方便,我把登录,退出,显示在线用户列表等功能都做在同一个jsp文件里了。
下面是具体的代码:

  1. /**
  2.  * OnlineUserListener.java
  3.  * Created on 2004-11-19
  4.  */
  5. package com.ccctc.view.web;
  6. import javax.servlet.http.HttpSessionEvent;
  7. import javax.servlet.http.HttpSessionListener;
  8. /**
  9.  * @author litf
  10.  * 
  11.  */
  12. public class OnlineUserListener
  13.     implements HttpSessionListener {
  14.     /**
  15.      * 浏览器第一次访问的时候,调用本方法
  16.      * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent)
  17.      */
  18.     public void sessionCreated(HttpSessionEvent event) {
  19.         User u = new User();
  20.         u.setName("guest");
  21.         u.setId(event.getSession().getId());
  22.         event.getSession().setAttribute("currentUser",u);
  23.         OnlineUsers.getInstance().addUser(u);
  24.     }
  25.     /**
  26.      * Session超时的时候,调用本方法
  27.      * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent)
  28.      */
  29.     public void sessionDestroyed(HttpSessionEvent event) {
  30.         OnlineUsers.getInstance().removeUser(event.getSession().getId());
  31.     }
  32. }


  1. /**
  2.  * OnlineUsers.java
  3.  * Created on 2004-11-19
  4.  */
  5. package com.ccctc.view.web;
  6. import java.util.Collection;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. import javax.servlet.http.HttpSession;
  10. import javax.servlet.http.HttpSessionBindingEvent;
  11. import javax.servlet.http.HttpSessionBindingListener;
  12. /**
  13.  * @author litf
  14.  * 在线用户统计
  15.  */
  16. public class OnlineUsers implements HttpSessionBindingListener{
  17.     private Map users = new HashMap();
  18.     
  19.     private static OnlineUsers onlineUsers = new OnlineUsers();
  20.     
  21.     public static OnlineUsers getInstance(){
  22.         return onlineUsers;
  23.     }
  24.     
  25.     /**
  26.      * @return
  27.      */
  28.     public Collection getUsers() {
  29.         return users.values();
  30.     }
  31.     
  32.     public void addUser(User user) {
  33.         users.put(user.getId(),user);
  34.     }
  35.     
  36.     public void removeUser(String userId){
  37.         users.remove(userId);
  38.     }
  39.     
  40.     /**
  41.      * 对象实例(即OnlineUserListener的实例)作为一个属性被设置到session的
  42.      * 时候,会调用本方法,这种情况一般发生在点击登录按钮以后的处理过程中
  43.      * 设置
  44.      * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)
  45.      */
  46.     public void valueBound(HttpSessionBindingEvent event) {
  47.         //现在暂时不需要额外处理,你可以在这里记录日志等
  48.     }
  49.     /**
  50.      * 当Session超时,或本实例被从session中移除的时候被调用,这种情况一般
  51.      * 发生在注销方法的处理过程中
  52.      * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
  53.      */
  54.     public void valueUnbound(HttpSessionBindingEvent event) {
  55.         try {
  56.             HttpSession session = event.getSession();
  57.             User u = (User)session.getAttribute("currentUser");
  58.             u.setName("guest");
  59.         } catch (RuntimeException e) {
  60.             //e.printStackTrace();
  61.         }
  62.     }
  63.     
  64. }


  1. /**
  2.  * User.java
  3.  * Created on 2004-11-19
  4.  */
  5. package com.ccctc.view.web;
  6. /**
  7.  * @author litf
  8.  * 
  9.  */
  10. public class User{
  11.     private String address;
  12.     private String id;
  13.     private String name;
  14.     /**
  15.      * @see java.lang.Object#equals(java.lang.Object)
  16.      */
  17.     public boolean equals(Object obj) {
  18.         if (obj == null || !(obj instanceof User)) {
  19.             return false;
  20.         }
  21.         if(this.id !=null && this.id.equals(((User)obj).getId())){
  22.             return true;
  23.         }
  24.         return false;
  25.     }
  26.     /**
  27.      * @return
  28.      */
  29.     public String getAddress() {
  30.         return address;
  31.     }
  32.     /**
  33.      * @return
  34.      */
  35.     public String getId() {
  36.         return id;
  37.     }
  38.     /**
  39.      * @return
  40.      */
  41.     public String getName() {
  42.         return name;
  43.     }
  44.     /**
  45.      * @param string
  46.      */
  47.     public void setAddress(String string) {
  48.         address = string;
  49.     }
  50.     /**
  51.      * @param string
  52.      */
  53.     public void setId(String string) {
  54.         id = string;
  55.     }
  56.     /**
  57.      * @param string
  58.      */
  59.     public void setName(String string) {
  60.         name = string;
  61.     }
  62.     
  63.     /**
  64.      * @see java.lang.Object#toString()
  65.      */
  66.     public String toString() {
  67.         return "name:"+name + ",id:" + id + ",address:"+address;
  68.     }
  69. }


test.jsp

  1. <%@ page import="com.ccctc.view.web.*" %>
  2. <%
  3. User u = (User)session.getAttribute("currentUser");
  4. String name = request.getParameter("user");
  5. if(u != null){
  6.     String remote = request.getRemoteAddr();
  7.     u.setAddress(remote);
  8.     
  9. }
  10. //User Login
  11. if(name != null){
  12.     if(u != null){
  13.         session.setAttribute("_listener",OnlineUsers.getInstance());
  14.         u.setName(name);
  15.         
  16.     }
  17. }
  18. //User Logout
  19. String logout = request.getParameter("logout");
  20. if(logout != null){
  21.     session.removeAttribute("_listener");
  22. }
  23. %>
  24. current users:<p>
  25. <% 
  26. java.util.Collection l = OnlineUsers.getInstance().getUsers();
  27. for(java.util.Iterator it = l.iterator(); it.hasNext();)
  28. {
  29.     User tu = (User)it.next();
  30.     if(u.equals(tu))
  31.     {
  32. %>
  33. <font color=red><%=tu.getName()%>:<%=tu.getAddress()%> </font>  
  34. <%
  35.     }else{
  36. %>
  37. <%=tu.getName()%>:<%=tu.getAddress()%>  
  38. <% 
  39.     }
  40. }
  41. %>
  42. <form action="/cctc/login.jsp">
  43. User : <input name="user" type="text"> <br>
  44. <input type="submit" name="Submit">
  45. </form>
  46. <p>
  47. <a href="/cctc/login.jsp?logout=true">Logout</a> <p>
  48. <a href="/cctc/login.jsp">refresh</a>


web.xml文件中增加:

  1.     <listener>
  2.         <listener-class>com.ccctc.view.web.OnlineUserListener</listener-class>
  3.     </listener>


附件:session_source.rar(2K)