java中使用session監(jiān)聽實(shí)現(xiàn)同帳號登錄限制、登錄人數(shù)限制
本文主要介紹了java中使用session監(jiān)聽實(shí)現(xiàn)同帳號登錄限制、登錄人數(shù)限制,具體代碼如下:
問題域:
1、同帳號登錄:若此帳號已登錄,不可再次登錄(與QQ模式相反)。
2、登錄人數(shù)限制,超過、已達(dá)人數(shù)限制則提示:系統(tǒng)繁忙,稍后再試。
解決思路:使用HttpSessionAttributeListener監(jiān)聽器(雖然我同時使用了HttpSessionListener不過感覺不好操作)
知識儲備:HttpSessionAttributeListener中有attributeAdd、attributeRemove、attributeReplace3個方法。
對session的setAttribute、removeAttribute將觸發(fā)attributeAdd、attributeRemove方法,對同一個session的同一個attribute進(jìn)行重復(fù)設(shè)置將觸發(fā)attributeReplace方法。
HttpSessionListener不好操作的原因:只要訪問jsp頁面便會創(chuàng)建session(訪問html并不會創(chuàng)建session,在server端,如servlet中調(diào)用HttpServletRequest.getSession(true)才會創(chuàng)建),jsp是動態(tài)頁,本質(zhì)就是個servlet。我的login.jsp顯然是個jsp,當(dāng)我在監(jiān)聽器中invalidate一個session,返回登錄頁,馬上就又創(chuàng)建了一個session。這是我感覺不清楚的地方,功夫沒到家。
具體實(shí)現(xiàn):
監(jiān)聽器代碼
public class OnlineListener implements HttpSessionListener, HttpSessionAttributeListener { private static List<SessionAndUser> sessions; static int delS = -1; static boolean flag = false; static { if (sessions == null) { sessions = Collections .synchronizedList(new ArrayList<SessionAndUser>()); } } public void sessionCreated(HttpSessionEvent hse) { System.out.println(hse.getSession() + "-" + new Date()); System.out.println(hse.getSession() + "-" + new Date()); } public void sessionDestroyed(HttpSessionEvent hse) { System.out.println("-------------sessionDestroyed()-----------"); System.out.println(hse.getSession() + " " + new Date(hse.getSession().getLastAccessedTime())); System.out.println(hse.getSession() + " " + new Date()); } public void attributeAdded(HttpSessionBindingEvent e) { System.out.println("-------------*start added*-----------------------" + sessions.size()); HttpSession session = e.getSession(); ActionContext ctx = ActionContext.getContext(); boolean newOne = true; String attrName = e.getName(); // 登錄 if (attrName.equals(Constant.USER_NAME)) { // 檢查登錄人數(shù) if (sessions.size() >= Constant.USER_LIMIT) { newOne = false; ctx.put("timeoutMSG", "serverBusy"); } String nowUser = (String) e.getValue(); // 遍歷所有session,檢查是否已經(jīng)登錄,若是則提示已經(jīng)登錄 for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(nowUser)) { newOne = false; ctx.put("timeoutMSG", "beenLoged");// tem.getSession().invalidate();// // 同賬號頂替登錄,自動調(diào)用remove break; } } // 新登錄帳號添加進(jìn)賬戶維護(hù)列表 if (newOne) { SessionAndUser sau = new SessionAndUser(); sau.setUserName(nowUser); sau.setSession(session); sau.setSid(session.getId()); sessions.add(sau); } } } public void attributeRemoved(HttpSessionBindingEvent e) throws IllegalStateException { HttpSession session = e.getSession(); System.out .println("-------------*start Removed*-----------------------" + sessions.size()); if (delS > -1) { if (flag) { sessions.remove(delS); flag = false; } } else { // 登錄 String attrName = e.getName(); if (attrName.equals(Constant.USER_NAME)) { String nowUser = (String) e.getValue(); // 遍歷所有session for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(nowUser)) { sessions.remove(i); break; } } } } } public void attributeReplaced(HttpSessionBindingEvent e) { HttpSession session = e.getSession(); System.out .println("-------------*start replace*-----------------------" + sessions.size()); String attrName = e.getName(); delS = -1; // 登錄 if (attrName.equals(Constant.USER_NAME)) { // User nowUser = (User) e.getValue();//old value String nowUser = (String) session.getAttribute(Constant.USER_NAME);// 當(dāng)前session中的user // 遍歷所有session for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(nowUser) && !tem.getSid().equals(session.getId())) { System.out.println("Remove:invalidate 1!"); delS = i; flag = true; } else if (tem.getSid().equals(session.getId())) { tem.setUserName(nowUser); } } if (delS != -1) { sessions.get(delS).getSession().invalidate();// 失效時自動調(diào)用了remove方法。也就會把它從sessions中移除了 } } } }
代碼主要思路是定義一個靜態(tài)List<SessionAndUser>存放session和帳號名稱。
登錄的Action中獲得監(jiān)聽器返回值并處理的代碼
session.setAttribute(Constant.USER_NAME, operator.getUsername()); ActionContext ctx = ActionContext.getContext(); if("serverBusy".equals(ctx.get("timeoutMSG"))){ ctx.put("timeoutMSG", "服務(wù)器繁忙,請稍后再試"); return "jump"; } if("beenLoged".equals(ctx.get("timeoutMSG"))){ ctx.put("timeoutMSG", "此賬戶在別處登錄"); return "jump"; }
頁面捕獲提示信息代碼
<%@taglib prefix="s" uri="/struts-tags"%> <s:property value="#attr.timeoutMSG" />
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- Java Web基于Session的登錄實(shí)現(xiàn)方法
- JavaWeb Session 會話管理實(shí)例詳解
- JavaWeb Session失效時間設(shè)置方法
- JAVAEE中用Session簡單實(shí)現(xiàn)購物車功能示例代碼
- Java中設(shè)置session超時(失效)的三種方法
- Java中Cookie和Session的那些事兒
- JavaWeb基于Session實(shí)現(xiàn)的用戶登陸注銷方法示例
- 詳解Java如何實(shí)現(xiàn)基于Redis的分布式鎖
- Java中使用Jedis操作Redis的示例代碼
- Java自定義注解實(shí)現(xiàn)Redis自動緩存的方法
- Java簡單實(shí)現(xiàn)session保存到redis的方法示例
相關(guān)文章
Java實(shí)現(xiàn)Dbhelper支持大數(shù)據(jù)增刪改
這篇文章主要介紹了Java實(shí)現(xiàn)Dbhelper支持大數(shù)據(jù)增刪改功能的實(shí)現(xiàn)過程,感興趣的小伙伴們可以參考一下2016-01-01java計(jì)算方差、標(biāo)準(zhǔn)差(均方差)實(shí)例代碼
在本篇文章里小編給大家分享了關(guān)于java計(jì)算方差、標(biāo)準(zhǔn)差(均方差)實(shí)例代碼以及相關(guān)知識點(diǎn),需要的朋友們可以參考下。2019-08-08