JAVAEE之單用戶登錄

[size=medium][b]單用戶登錄是系統中數據一直性的解決方案之一。[/b][/size]

[b]問題背景:[/b]
試想,如果同時有兩個用戶使用一個賬號登錄系統,
他們兩個人需要對一批文章進行編輯。
都已經把同一篇文章讀取到了瀏覽器中各自進行編輯後提交,
那麼就會出現該文章只會保存一個人提交的結果。
先提交的那個人的將會被覆蓋掉。


[b]核心思想:[/b]
背景:由於每次請求的 sessionId 都不一樣。
確保:每個用戶名只能對應一個 session
方法:
在全局變量中維護一個 session 列表。
如果相同的用戶名,出現不一樣的 sessionId,
說明該用戶進行了第二次登錄,
則使原來存在的 session 失效(移除 session )。

頁面可以加輪詢次數(時間)控制,
無需等到用戶下一次手動提交請求。


[b]1、第一次登陸成功[/b]

String userIdDecode = "登陸名";
ServletContext context=null;
context = this.getSession().getServletContext();
HttpSession session = this.getSession();
Map<String,HttpSession> usersMap = (Map<String, HttpSession>) context.getAttribute("usersMap");
//第一個用戶登錄時
if(usersMap == null){
usersMap = new HashMap<String,HttpSession>();
usersMap.put(userIdDecode, session);
context.setAttribute("usersMap", usersMap); //將用戶保存到ServletContext對象中
//非第一個用戶登錄
}else{
if(usersMap.containsKey(userIdDecode)){
logger.info("第二次登陸,remove掉"+userIdDecode);
usersMap.remove(userIdDecode);
}
logger.info("添加當前用戶到map"+userIdDecode);
usersMap.put(userIdDecode, session);
}
this.setSessionValue("user", userIdDecode);

說明:
這裏不用把整個session放到全局變量中,
可以只放一個 seesionId 即可。


[b]2、攔截器攔截每一個請求路徑,判斷用戶是否已經在別處登錄[/b]
 

//獲取用戶信息
HttpSession session = this.getSession();

String user = (String)session.getAttribute("user");
System.out.println("當前登陸用戶:"+user+"當前用戶的sessionId"+session.getId());

Map<String,HttpSession> usersMap = (Map<String, HttpSession>) session.getServletContext().getAttribute("users");
if(null != usersMap){
if(null == user){
result = "";
return null;
}
if(usersMap.containsKey(user)){
if(session.getId().equals(usersMap.get(user).getId()))
result = "true";
else
result = "false";
}else {
if(null==usersMap.get(user))
result = "true";
else
result = "false";
}
}else{
result = "";
}

try {
ServletActionContext.getResponse().getWriter().print(result);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return null;

}


[b]3、前臺ajax輪詢用戶當前狀態[/b]

//如果是在首頁結束輪詢
var countTimeOut = 0;
//輪詢當前用戶
var t2 = window.setInterval("loadXMLDoc()",1000);
function loadXMLDoc()
{
countTimeOut = countTimeOut+1;
if(countTimeOut == 1800){
$.ajax({
type:"post",
url:"cleanSession",
dataType : "text",
error:function(){
window.location.href="http://toIndex.action";
}
});
}
$.ajax({
type:"post",
url:"sessionLive",
dataType : "text",
success:function(data){check(data)},
error:function(){
window.location.href="http://toIndex.action";
}
});
}

function check(result){
if(result=="true"){
}else{
if(result=="false"){
alert("您已經在別處登陸");
$.ajax({
type:"post",
url:"cleanSession",
dataType : "text",
error:function(){
window.location.href="http://toIndex.action";
}
});
window.location.href="http://toIndex.action";
}else{
clearInterval(t2);
}
}
}
//輪詢當前用戶結束



[b]4、清除當前session信息[/b]

//獲取用戶信息
String user = (String)this.getSession().getAttribute("user");
Map<String,HttpSession> usersMap = new HashMap<String, HttpSession>();
HttpSession session = this.getSession();
usersMap = (Map<String, HttpSession>)session.getServletContext().getAttribute("users");
if(null != usersMap){
if(usersMap.containsKey(user)){
if(session.getId().equals(usersMap.get(user).getId())) {
usersMap.remove(user);
}
}}
this.getSession().invalidate();


[b]5、監聽器[/b]

application = event.getSession().getServletContext();
Map<String,HttpSession> usersMap = new HashMap<String, HttpSession>();
HttpSession session = event.getSession();
String user = (String)session.getAttribute("user");
usersMap = (Map<String, HttpSession>)application.getAttribute("users");
if(null != usersMap){
if(usersMap.containsKey(user)){
if(session.getId().equals(usersMap.get(user).getId())){
usersMap.remove(user);
}
}
}
//將session設置成無效
event.getSession().invalidate();
System.out.println("一個Session被銷燬了!"+user);



-
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章