统计在线人数以及在线人信息

通过监听Session对象的方式来实现在线人数的统计和在线人信息展示,并且让超时的自动销毁

1. web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!--  统计在线人数-->
    <listener>
        <listener-class>com.wri.itmag.OnlineCounterListener</listener-class>
    </listener>
    
    <!-- session超时定义,单位为分钟  update by ChangPeng 2014-04-24 session超时时间设置为30分钟 -->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

</web-app>

2.OnlineCounterListener.java

      对Session对象实现监听,首先必须继承HttpSessionListener类,该程序的基本原理就是当浏览者访问页面的时候必定会产生一个session对象;当关闭该页面的时候必然会删除该session对象。所以每当产生一个新的session对象就让在线人数加1,当删除一个session对象就让在线人数减1。还要继承一个HttpSessionAttributeListener,来实现对其属性的监听。分别实现attributeAdded方法,attributeReplace方法以及attributeRemove方法。

sessionCreated//新建一个会话时候触发也可以说是客户端第一次和服务器交互时候触发

sessionDestroyed//销毁会话的时候  一般来说只有某个按钮触发进行销毁 或者配置定时销毁 ( 很多文献中提到说浏览器关闭时候会销毁 但是楼主通过各种现行主流浏览器测试效果不尽如人意)

HttpSessionAttributeListener有3个接口需要实现

attributeAdded//在session中添加对象时触发此操作 笼统的说就是调用setAttribute这个方法时候会触发的

attributeRemoved//修改、删除session中添加对象时触发此操作  笼统的说就是调用 removeAttribute这个方法时候会触发的

attributeReplaced//在Session属性被重新设置时

 1 package com.wri.itmag;
 2 
 3 import java.util.ArrayList;
 4 import java.util.HashMap;
 5 import java.util.HashSet;
 6 import java.util.List;
 7 import java.util.Map;
 8 import java.util.Set;
 9 
10 import javax.servlet.http.HttpSessionAttributeListener;
11 import javax.servlet.http.HttpSessionBindingEvent;
12 import javax.servlet.http.HttpSessionEvent;
13 import javax.servlet.http.HttpSessionListener;
14 
15 import com.wri.itmag.vo.personalInfo.UserVO;
16 
17 public class OnlineCounterListener implements HttpSessionListener,
18         HttpSessionAttributeListener {
19     public static int onLineCount; // 用于统计在线人数
20     /**
21      * 查询在线人名称,用于前台页面对于在线人名称的展示  
22      */
23     public static Set<String> onLinePersonList = new HashSet<String>();//用于
24     /**
25      * 用于查询在线人详细信息
26      */
27     private Map<String, Object> sessionMap = new HashMap<String, Object>();
28 
29     public void sessionCreated(HttpSessionEvent hse) {
30         // HttpSession session = hse.getSession();
31         // sessionMap.put(session.getId(), session);
32         // onLineCount = sessionMap.size();
33     }
34 
35     public void sessionDestroyed(HttpSessionEvent hse) {
36         // onLineCount = sessionMap.size();
37     }
38 
39     public void attributeAdded(HttpSessionBindingEvent hsbe) {
40 
41         String name = hsbe.getName();
42         if ("userVO".equals(name)) {
43             UserVO userVO = (UserVO) hsbe.getValue();
44             sessionMap.put(userVO.getId() + "", userVO);
45             onLineCount = sessionMap.size();
46             onLinePersonList.add(userVO.getUser_name());
47         }
48     }
49 
50     public void attributeRemoved(HttpSessionBindingEvent hsbe) {
51         String name = hsbe.getName();
52         if ("userVO".equals(name)) {
53             UserVO userVO = (UserVO) hsbe.getValue();
54             sessionMap.remove(userVO.getId() + "");
55             onLineCount = sessionMap.size();
56             //System.out.println(userVO.getId() + "" + userVO.getUser_name());
57             onLinePersonList.remove(userVO.getUser_name());
58         }
59 
60     }
61 
62     public void attributeReplaced(HttpSessionBindingEvent hsbe) {
63     
64         String name = hsbe.getName();
65         if ("userVO".equals(name)) {
66             UserVO userVO = (UserVO) hsbe.getValue();
67             sessionMap.remove(userVO.getId() + "");
68             onLineCount = sessionMap.size();
69             onLineCount++;
70             onLinePersonList.remove(userVO.getUser_name());
71         }
72     }
73 
74 }

3.LoginAction.java

      实现用户登录,登出,以及登录成功页面跳转的功能

  1 package com.wri.itmag.action.login;
  2 
  3 import java.io.IOException;
  4 import java.text.SimpleDateFormat;
  5 import java.util.ArrayList;
  6 import java.util.Arrays;
  7 import java.util.Date;
  8 import java.util.List;
  9 
 10 import javax.servlet.ServletException;
 11 import javax.servlet.http.HttpServletRequest;
 12 import javax.servlet.http.HttpServletResponse;
 13 import javax.servlet.http.HttpSession;
 14 
 15 import net.sf.json.JSONObject;
 16 
 17 import com.wri.itmag.OnlineCounterListener;
 18 import com.wri.itmag.action.BaseAction;
 19 import com.wri.itmag.common.LoginUserLog;
 20 import com.wri.itmag.service.personalInfo.UserInfoService;
 21 import com.wri.itmag.service.syscfg.DataDictManageService;
 22 import com.wri.itmag.vo.personalInfo.UserVO;
 23 
 24 public class LoginAction extends BaseAction {
 25     private UserInfoService userInfoService;
 26     private String userAccount;
 27     private String password;
 28 
 29     /**
 30      * 登录操作
 31      */
 32     public String login() throws Exception {
 33         UserVO userVO = null;
 34         HttpSession session = this.getSession();
 35         try {
 36             userVO = userInfoService.checkUser(userAccount, password);
 37 
 38         } catch (Exception e) {
 39             e.printStackTrace();
 40             throw e;
 41         }
 42         try {
 43             if (userVO != null) {
 44                 HttpServletRequest request = this.getRequest();
 45                 // 登陆信息
 46                 LoginUserLog loginUserLog = new LoginUserLog(userVO.getId(),
 47                         request.getRemoteAddr());
 48                 // 放入session
 49                 session.setAttribute("loginUserLog", loginUserLog);
 50                 session.setAttribute("userVO", userVO);
 51                 session.setAttribute("userJson", JSONObject.fromObject(userVO));
 52                 this.outJsonString("{success:true,message:'登陆成功'}");
 53             } else {
 54                 this.outJsonString("{success:false,message:'请检查用户名和密码....'}");
 55             }
 56         } catch (Exception ex) {
 57             ex.printStackTrace();
 58             throw ex;
 59         }
 60         return null;
 61     }
 62 
 63     
 64     /**
 65      * 用户退出
 66      */
 67     public String logout() throws Exception {
 68         HttpSession session = this.getSession();
 69 
 70         // 从session中获取用户信息
 71         UserVO userVO = (UserVO) session.getAttribute("userVO");
 72         LoginUserLog loginUserLog = (LoginUserLog) session
 73                 .getAttribute("loginUserLog");
 74         if (loginUserLog != null) {
 75             if (loginUserLog.isExist(loginUserLog.getUid())) {
 76                 session.setAttribute("loginUserLog", null);
 77                 session.setAttribute("userVO", null);
 78                 session.invalidate();
 79             }
 80         }
 81 
 82         // session.setAttribute("userVO", null);
 83         // session.invalidate();
 84 
 85         this.outJsonString("{success:true}");
 86         return null;
 87     }
 88 
 89     /**
 90      * 登录成功操作
 91      */
 92     public String loginSucc() throws ServletException, IOException {
 93         // 传递角色
 94         HttpSession session = this.getSession();
 95         UserVO userVO = (UserVO) session.getAttribute("userVO");
 96         this.outJsonString("{success:true,userVO:'"
 97                 + JSONObject.fromObject(userVO) + "',isMyDemand:'" + isMyDemand
 98                 + "'}");
 99         return null;
100     }
101 
102     /**
103      * 登陆成功后跳转到主界面
104      */
105     public String jump() throws ServletException, IOException {
106         HttpSession session = this.getSession();
107         HttpServletRequest request = this.getRequest();
108         HttpServletResponse response = this.getResponse();
109         if (session.isNew()) {
110             response.sendRedirect("login.html");
111         } else {
112             UserVO userVO = (UserVO) session.getAttribute("userVO");
113             if (userVO != null) {
114                 request.setAttribute("userVO", userVO);
115                 request.setAttribute("logTime", new SimpleDateFormat(
116                         "yyyy-MM-dd").format(new Date()));
117                 request.setAttribute("onlineCount",
118                         OnlineCounterListener.onLineCount);
119 
120                 request.setAttribute("onLinePersonList",
121                         OnlineCounterListener.onLinePersonList);
122                 request.getRequestDispatcher("/WEB-INF/main.jsp").forward(
123                         request, response);
124             } else {
125                 response.sendRedirect("login.html");
126             }
127         }
128         return null;
129     }
130 }

4.main.jsp   做页面展示 :在登陆完成后跳转到主页面就会显示在线人数,鼠标移至人数上时候,就会显示所有在线人信息,鼠标移出就自动隐藏。

...
<span title=""
                style="font-size: 13px; font-family: 宋体; position: absolute; right: 5px;  80px;" onmouseover="showOnLinePersonList()" onmouseout="hideOnLinePersonList()">&nbsp;&nbsp;在线:${onlineCount}人
                
                </span>
            <span  id="onlinePersonList" style="display:none;font-size: 13px; font-family: 宋体; position: absolute; top:10px ;right: 10px;  80px;">
               <div id="firstDiv"  align="center" style="backgroud-color:#8069ff ;border-style:solid;border-1px">所有在线人</div>
                <div  id="secondDiv" align="center">
                <c:forEach items="${onLinePersonList}" var ="list">
                &nbsp;<ol ><c:out value="${list}"/>&nbsp;&nbsp;</ol>
                </c:forEach>
                </div>
                </span>
.....
<script>

function showOnLinePersonList(){
     document.getElementById('onlinePersonList').style.display="block";
    
}
function hideOnLinePersonList(){
   document.getElementById('onlinePersonList').style.display="none";
}

</script>

未解决的问题:以上的代码可以成功的实现在线人数的统计,但是对于在线展示在线人信息的时候,还有bug存在。出现的情况为:如果在同一个客户端,一个用户登录之后,没有做登出的操作(即session没有销毁),此时再以另一个用户登录,这个时候就相当于session中的name为“uservo”的attribute被替换了,也就调用了OnlineCounterListener类中的attributeReplace方法,代码如下:onLinePersonList先要remove掉之前的用户,加入新的用户,但是attributeRemoved(HttpSessionBindingEvent hsbe)中hsbe.getValue()拿到的是之前的值,没法拿到新的用户的值,所以不知道如何把新登录的这个用户加到set里面去,求解!!!

 if ("userVO".equals(name)) {
             UserVO userVO = (UserVO) hsbe.getValue();
             sessionMap.remove(userVO.getId() + "");
             onLineCount = sessionMap.size();
             onLineCount++;
             onLinePersonList.remove(userVO.getUser_name());
         }
web开发过程中的问题总结
原文地址:https://www.cnblogs.com/muwanqing/p/4520312.html