統計線上使用者數以及同賬號登入踢出另一使用者
阿新 • • 發佈:2019-01-11
寫一個session屬性監聽器:定義兩個map,一個存session,以使用者編號為key;一個存使用者資訊,也以使用者編號為key.map的個數就是線上使用者數.每個使用者登入時,先檢查map中是否存在,如果不存在,就新增到map裡面去,如果存在,就通過使用者編號找對應session使其失效.再將當前登入使用者資訊寫入到map裡面.
package com.sunshine.monitor.comm.filter; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; import com.sunshine.monitor.system.manager.bean.SysUser; /** * session屬性監聽,用於統計線上使用者數,同一賬戶登入踢出線上使用者 * 對於直接關閉瀏覽器的操作等待session失效之後,才能做到清除. * @date 2016-6-1 * @author licheng * */ public class SessionListener implements HttpSessionAttributeListener{ /** * 定義監聽的session屬性名 */ public final static String LISTENER_NAME = "_login"; public final static String LISTENER_COUNT = "_count"; /** * 定義儲存客戶登入使用者的集合 */ private static Map<String, SysUser> users = new HashMap<String, SysUser>(); /** * 定義儲存客戶登入session的集合 */ private static Map<String, HttpSession> sessions = new HashMap<String, HttpSession>(); /** * 定義儲存線上使用者數的集合 */ private static Map<String, Integer> counts = new HashMap<String, Integer>(); /** * 加入session時的監聽方法 * * @param HttpSessionBindingEvent * session事件 */ public void attributeAdded(HttpSessionBindingEvent sbe) { if(LISTENER_NAME.equals(sbe.getName())){ SysUser s = (SysUser) sbe.getValue(); if(users.containsKey(s.getYhdh())) { HttpSession session = sessions.get(s.getYhdh()); session.removeAttribute(LISTENER_NAME); session.invalidate(); } sessions.put(s.getYhdh(), sbe.getSession()); users.put(s.getYhdh(), s); } Integer count = users.size(); counts.put(LISTENER_COUNT, count); } /** * session失效時的監聽方法 * * @param HttpSessionBindingEvent * session事件 */ public void attributeRemoved(HttpSessionBindingEvent sbe) { if(LISTENER_NAME.equals(sbe.getName())){ // 從session集合中減去一個 SysUser s = (SysUser) sbe.getValue(); sessions.remove(s.getYhdh()); users.remove(s.getYhdh()); counts.put(LISTENER_COUNT, users.size()); } } /** * session覆蓋時的監聽方法 * * @param HttpSessionBindingEvent * session事件 */ public void attributeReplaced(HttpSessionBindingEvent sbe) { } public static Map<String, SysUser> getUsers() { return users; } public static Map<String, HttpSession> getSessions() { return sessions; } public static Map<String, Integer> getCounts() { return counts; } }
監聽器寫好之後要在web.xml裡面配置一下.
<listener>
<listener-class>com.sunshine.monitor.comm.filter.SessionListener</listener-class>
</listener>
如何使用呢,使用者登入時給session設定一個數據,獲取線上使用者數
request.getSession().setAttribute(SessionListener.LISTENER_NAME, s); application.setAttribute("online", SessionListener.getCounts().get(SessionListener.LISTENER_COUNT));
頁面上的線上人數這樣獲取:
<c:out value="${online}"></c:out>
登出時,這樣寫:
/** * 登出移除sesson,從設定application的onlines屬性 * @param request * @param response * @return */ @RequestMapping public ModelAndView logout(HttpServletRequest request, HttpServletResponse response){ ModelAndView mv = new ModelAndView(forwardLoginPath); HttpSession session = request.getSession(); session.removeAttribute(SessionListener.LISTENER_NAME); session.invalidate(); session.getServletContext().setAttribute("online", SessionListener.getCounts().get(SessionListener.LISTENER_COUNT)); return mv; }
如果使用者非法退出,如直接關閉瀏覽器,關閉視窗等.這時session並不會立即失效.我嘗試過使用js監聽視窗關閉操作,然後移除session.可是這段js只適用於ie8及以下.最終放棄,只能等待session失效.session的失效時常是在web.xml裡面設定的.
session失效時,也是會觸發屬性移除時間的.