問題描述:
當(dāng)在標(biāo)簽a中使用用戶A登錄后,再打開標(biāo)簽b,進(jìn)入登錄界面使用用戶B再次進(jìn)行登錄。那么標(biāo)簽a中的登錄信息就變成了用戶B的登錄信息。這種情況顯示不是用戶希望得到的。
兩個(gè)標(biāo)簽頁共用一個(gè)session。后一個(gè)把前一個(gè)的同名attribute域覆蓋了,致使數(shù)據(jù)混亂。
解決辦法:
辦法一:
目標(biāo):實(shí)現(xiàn)多標(biāo)簽中登錄多個(gè)用戶而互不影響。
思路:將用戶登錄信息,比如用戶編號、登錄ip等封裝到一個(gè)對象,然后以一個(gè)唯一值(比如登錄時(shí)間)為key放入HashMap,再將HashMap放入session。
首先action中attribute的名字不能重復(fù)。
// 避免同一PC多瀏覽器窗口不同賬戶共用session
Random random = new Random();
StringBuffer sid = new StringBuffer();
sid = sid.append(System.currentTimeMillis()); // 取系統(tǒng)時(shí)間
// 加上10為0-9隨機(jī)數(shù)確保sid不重復(fù)
for (int i = 0; i < 10; i++) {
sid = sid.append(random.nextInt(10));
}
// 把所有需要放進(jìn)session的attribute放進(jìn)一個(gè)Mapbar<String, Object>
// 一是便于el中取值、二是便于統(tǒng)一管理
Map sessionMap = new HashMap();
sessionMap.put("session_urname", urname);
session.setAttribute(sid.toString(), sessionMap);
String rd = "detail.jsp?sid=" + sid.toString();
request.getRequestDispatcher(rd).forward(request, response);
然后在jsp中用EL取值:
${sessionScope[param.sid].session_urname}
給session_urname加上一層Map,看似多余,其實(shí)不然。有兩點(diǎn)考慮,一是便于EL取值,如果有多個(gè)變量需要放到session里,如果不用Map,勢必要這樣寫:
session.setAttribute("name" + sid.toString(), urname);
session.setAttribute("pwd" + sid.toString(), urpassword);
你也許會(huì)想EL中取值時(shí)加上前綴唄:
${sessionScope['name' + param.sid]}
很可惜EL并不支持+號的字符串連接操作,這樣寫就不能用EL了;二是把所有需要放入session的變量都放入Map里便于管理,特別是在字段很多的情況下。
辦法二:
目標(biāo):退而求其次,打開新標(biāo)簽頁進(jìn)行登錄,再切換到舊標(biāo)簽頁時(shí),提示頁面已失效。如果打開新標(biāo)簽頁,地址欄中直接輸入主頁面地址,則以同一用戶進(jìn)行登錄。2個(gè)標(biāo)簽頁的內(nèi)容都有效。
思路:服務(wù)器在創(chuàng)建session時(shí)會(huì)為每個(gè)session分配一個(gè)唯一的sessionId,因此我們可以根據(jù)它來想辦法。首先定義一個(gè)public static 類型的HashMap:checkMap。假設(shè)我的登錄頁面為login.jsp,主頁面為main.jsp。后臺(tái)執(zhí)行登錄檢查的方法為checkLogin()。當(dāng)執(zhí)行登錄檢查的時(shí)候:
//獲得sessionId
String sessionId = session.getId;
//標(biāo)示頁面是否有效的值
int checkVal;
if(checkMap.containsKey(sessionId)) {
checkVal = (Integer)checkMap.get(sessionId) + 1;
} else {
checkVal = 1;
}
checkMap.put(sessionId,checkVal);
當(dāng)?shù)卿洺晒ΓM(jìn)入main.jsp頁面時(shí),首先根據(jù)sessionId獲得checkVal并存入一個(gè)頁面級的變量。下面就開始判斷了,每次標(biāo)簽頁獲得焦點(diǎn)時(shí)(window.onfocus)就將頁面中的變量與后臺(tái)根據(jù)sessionId從checkMap中得到的checkVal進(jìn)行比較,如果不想同,說明該頁面已經(jīng)失效,提示信息并關(guān)閉該頁面。
但是仍有一個(gè)問題,window.onfocus不知道為什么在頁面獲得焦點(diǎn)時(shí)會(huì)執(zhí)行很多次?
posted on 2012-06-08 09:33
飛翔天使 閱讀(6922)
評論(0) 編輯 收藏 所屬分類:
JSP