經過監聽Session對象的方式來實如今線人數的統計和在線人信息展現,而且讓超時的自動銷燬html
1. web.xmljava
<?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.javaweb
對Session對象實現監聽,首先必須繼承HttpSessionListener類,該程序的基本原理就是當瀏覽者訪問頁面的時候一定會產生一個session對象;當關閉該頁面的時候必然會刪除該session對象。因此每當產生一個新的session對象就讓在線人數加1,當刪除一個session對象就讓在線人數減1。還要繼承一個HttpSessionAttributeListener,來實現對其屬性的監聽。分別實現attributeAdded方法,attributeReplace方法以及attributeRemove方法。json
sessionCreated//新建一個會話時候觸發也能夠說是客戶端第一次和服務器交互時候觸發瀏覽器
sessionDestroyed//銷燬會話的時候 通常來講只有某個按鈕觸發進行銷燬 或者配置定時銷燬 ( 不少文獻中提到說瀏覽器關閉時候會銷燬 可是樓主經過各類現行主流瀏覽器測試效果不盡如人意)服務器
HttpSessionAttributeListener有3個接口須要實現session
attributeAdded//在session中添加對象時觸發此操做 籠統的說就是調用setAttribute這個方法時候會觸發的app
attributeRemoved//修改、刪除session中添加對象時觸發此操做 籠統的說就是調用 removeAttribute這個方法時候會觸發的jsp
attributeReplaced//在Session屬性被從新設置時ide
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; width: 80px;" onmouseover="showOnLinePersonList()" onmouseout="hideOnLinePersonList()"> 在線:${onlineCount}人 </span> <span id="onlinePersonList" style="display:none;font-size: 13px; font-family: 宋體; position: absolute; top:10px ;right: 10px; width: 80px;"> <div id="firstDiv" align="center" style="backgroud-color:#8069ff ;border-style:solid;border-width:1px">全部在線人</div> <div id="secondDiv" align="center"> <c:forEach items="${onLinePersonList}" var ="list"> <ol ><c:out value="${list}"/> </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()); }