需求:同一個專案,防止重復登錄
判斷代碼:
ervletContext context=request.getSession().getServletContext();sessionSet在監聽器中保存每一個session
HashSet<HttpSession> sessionSet=(HashSet<HttpSession>) context.getAttribute("sessionSet");
for(HttpSession s:sessionSet){
//判斷sessionId是否不同
if(session.getId() != s.getId()) {
//判斷用戶是否重復
if (session.getAttribute("loginName").equals(s.getAttribute("loginName"))) {
sessionSet.remove(session);
return ResponseMessageEnum.ERROR_USER_HAS_LOGIN.toString();
}
}
}
當前完成效果:正常使用,無法登錄已經在線的用戶,直到其注銷退出。
當前存在問題:但是許多用戶習慣直接關閉瀏覽器,此時在session的有效時間內無法登錄,這在實際個人使用中非常不便
曾嘗試過的方法:1.在HTML中添加類似于監控瀏覽器退出的操作,這些方法目前都已不行。
2.給session設定有效時間,但時間短了會影響用戶在線使用體驗,時間長了就沒啥意義
請問各位大佬:還有沒有更好的方法?
uj5u.com熱心網友回復:
設定一個退出按鈕,用戶點擊退出清除session加一個攔截器,只能訪問靜態的登錄頁面,登錄頁面判斷如果session有用戶資訊
直接跳轉到index
uj5u.com熱心網友回復:
正常退出功能是沒問題的,問題是如果是瀏覽器退出的話,之前的session依舊存在在服務器中,這邊在登錄就是一個新的session加同樣的賬號,這就是標準的一個重復登錄的現象了。那么在session失效之前都不能登,這里我該怎么做?
uj5u.com熱心網友回復:
其實你真正的問題無非就是怕用戶再次訪問登錄頁面造成重復登錄,因為正常訪問網址驗證是否有session,有就直接訪問,沒有就攔截登錄 ,但是的確會存在用戶直接訪問登錄頁面,但是這有什么關系,只要你的session用的是同一個屬性名,再次登錄之后又不會存在兩個不同屬性名的session,就像我訪問登錄淘寶,但是我依舊可以重新打開一個視窗再次登錄淘寶,它沖突嗎?如果你是在不希望這樣,可以在登錄的時候先取出session臨時保存,登錄成功之后再判斷session是不是一樣,一樣就把之前洗掉掉就行了uj5u.com熱心網友回復:
==》當前存在問題:但是許多用戶習慣直接關閉瀏覽器,此時在session的有效時間內無法登錄,這在實際個人使用中非常不便此時繼續登錄的話,已經重新驗證登錄的用戶的有效性,直接覆寫原來的資訊即可。不用考慮太復雜。
uj5u.com熱心網友回復:
沒辦法,目前要求就是實作禁止后來者登錄相同用戶,目前準備通過瀏覽器和服務器建立websocket長連接來判斷瀏覽器是否關閉uj5u.com熱心網友回復:
這個問題目前已經解決了,我這里簡單說明一下。我主要使用了websocket,放在專案首頁,即一登錄成功進入首頁,就會建立websocket連接,服務器中對應的是有websocket相關的三個方法,創建時,關閉時,發送資訊與回應資訊。當websocket連接關閉時,說明用戶不在線,即可能正常退出,也可能例外退出。正常退出在后面的控制器判斷是否重復的時候就跳過了,不用考慮。只需把他當做例外退出。這里需要注意一下,當多用戶連接時,無法判斷用戶與websocket 之間的對應關系,所以需要在前端將用戶名資訊傳遞進來,隨便用一個表單隱藏域,將變數附加在url上,然后在服務器端寫個方法,獲取url后把用戶名決議出來。設定一個靜態變數集合list,在關閉的時候,在c關閉方法中將該條websocket的用戶名放入list中。在新建連接時,說明用戶剛登陸,在創建方法中,判斷list是否有之前退出過的用戶名與當前用戶名一致,有就把他從集合中洗掉。到這里list就可以用了,在控制器中獲取list,這里之前設的是靜態變數,可以直接用。現在的專案登錄時,應該都是有將session或session資訊存進集合,我這是上面可以看到,將session物件放入了set里。然后遍歷,遍歷時,先判斷前后session的id是否一致,再判斷前后存的用戶名資訊是否一致(這里如果用戶正常退出,set中是沒有對應的session的,所以走不進來),此時已經到了重復登錄處理的步驟,判斷前登錄用戶的用戶名資訊是否在list集合中,不在則說明正在使用中,并將當前session從集合中,方法直接return掉,前臺ajax接收資訊并提示用戶已登錄。uj5u.com熱心網友回復:
緊接上文,在list中說明,用戶例外退出了,這時將前登錄session從集合中去掉,代碼繼續往下走,用戶可以用當前session直接登錄。到這里功能就算完成了。注意可能會報一個跟集合有關的錯,叫ConcurrentModificationException,具體百度,解決方案,使用Iterator遍歷集合,使用Iterator的remove方法,而不是list.remove.
到這里,這個重復登錄應該完成了,是否有問題目前不知。出現問題也請告訴我一下!具體代碼不多,跟著我的思路就可以
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/157191.html
標籤:Java EE
上一篇:I Want to Learn Java, Find Someone Who Likes to Teach Me.
