java中使用session監(jiān)聽實(shí)現(xiàn)同帳號(hào)登錄限制、登錄人數(shù)限制
本文主要介紹了java中使用session監(jiān)聽實(shí)現(xiàn)同帳號(hào)登錄限制、登錄人數(shù)限制,具體代碼如下:
問(wèn)題域:
1、同帳號(hào)登錄:若此帳號(hào)已登錄,不可再次登錄(與QQ模式相反)。
2、登錄人數(shù)限制,超過(guò)、已達(dá)人數(shù)限制則提示:系統(tǒng)繁忙,稍后再試。
解決思路:使用HttpSessionAttributeListener監(jiān)聽器(雖然我同時(shí)使用了HttpSessionListener不過(guò)感覺(jué)不好操作)
知識(shí)儲(chǔ)備:HttpSessionAttributeListener中有attributeAdd、attributeRemove、attributeReplace3個(gè)方法。
對(duì)session的setAttribute、removeAttribute將觸發(fā)attributeAdd、attributeRemove方法,對(duì)同一個(gè)session的同一個(gè)attribute進(jìn)行重復(fù)設(shè)置將觸發(fā)attributeReplace方法。
HttpSessionListener不好操作的原因:只要訪問(wèn)jsp頁(yè)面便會(huì)創(chuàng)建session(訪問(wèn)html并不會(huì)創(chuàng)建session,在server端,如servlet中調(diào)用HttpServletRequest.getSession(true)才會(huì)創(chuàng)建),jsp是動(dòng)態(tài)頁(yè),本質(zhì)就是個(gè)servlet。我的login.jsp顯然是個(gè)jsp,當(dāng)我在監(jiān)聽器中invalidate一個(gè)session,返回登錄頁(yè),馬上就又創(chuàng)建了一個(gè)session。這是我感覺(jué)不清楚的地方,功夫沒(méi)到家。
具體實(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();//
// 同賬號(hào)頂替登錄,自動(dòng)調(diào)用remove
break;
}
}
// 新登錄帳號(hào)添加進(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();// 失效時(shí)自動(dòng)調(diào)用了remove方法。也就會(huì)把它從sessions中移除了
}
}
}
}
代碼主要思路是定義一個(gè)靜態(tài)List<SessionAndUser>存放session和帳號(hào)名稱。
登錄的Action中獲得監(jiān)聽器返回值并處理的代碼
session.setAttribute(Constant.USER_NAME, operator.getUsername());
ActionContext ctx = ActionContext.getContext();
if("serverBusy".equals(ctx.get("timeoutMSG"))){
ctx.put("timeoutMSG", "服務(wù)器繁忙,請(qǐng)稍后再試");
return "jump";
}
if("beenLoged".equals(ctx.get("timeoutMSG"))){
ctx.put("timeoutMSG", "此賬戶在別處登錄");
return "jump";
}
頁(yè)面捕獲提示信息代碼
<%@taglib prefix="s" uri="/struts-tags"%> <s:property value="#attr.timeoutMSG" />
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- Java Web基于Session的登錄實(shí)現(xiàn)方法
- JavaWeb Session 會(huì)話管理實(shí)例詳解
- JavaWeb Session失效時(shí)間設(shè)置方法
- JAVAEE中用Session簡(jiǎn)單實(shí)現(xiàn)購(gòu)物車功能示例代碼
- Java中設(shè)置session超時(shí)(失效)的三種方法
- Java中Cookie和Session的那些事兒
- JavaWeb基于Session實(shí)現(xiàn)的用戶登陸注銷方法示例
- 詳解Java如何實(shí)現(xiàn)基于Redis的分布式鎖
- Java中使用Jedis操作Redis的示例代碼
- Java自定義注解實(shí)現(xiàn)Redis自動(dòng)緩存的方法
- Java簡(jiǎn)單實(shí)現(xiàn)session保存到redis的方法示例
相關(guān)文章
java實(shí)現(xiàn)批量導(dǎo)入.csv文件到mysql數(shù)據(jù)庫(kù)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)批量導(dǎo)入.csv文件到mysql數(shù)據(jù)庫(kù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
實(shí)戰(zhàn)分布式醫(yī)療掛號(hào)通用模塊統(tǒng)一返回結(jié)果異常日志處理
這篇文章主要為大家介紹了實(shí)戰(zhàn)分布式醫(yī)療掛號(hào)系統(tǒng)之統(tǒng)一返回結(jié)果統(tǒng)一異常處理,統(tǒng)一日志處理到通用模塊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-04-04
Java多態(tài)和實(shí)現(xiàn)接口的類的對(duì)象賦值給接口引用的方法(推薦)
下面小編就為大家?guī)?lái)一篇Java多態(tài)和實(shí)現(xiàn)接口的類的對(duì)象賦值給接口引用的方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
基于Spring Batch向Elasticsearch批量導(dǎo)入數(shù)據(jù)示例
本文介紹了基于Spring Batch向Elasticsearch批量導(dǎo)入數(shù)據(jù)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
SpringBoot+Redis實(shí)現(xiàn)接口防刷的示例代碼
在實(shí)際開發(fā)中,會(huì)出現(xiàn)用戶多次點(diǎn)擊發(fā)送請(qǐng)求,本文主要介紹了SpringBoot+Redis實(shí)現(xiàn)接口防刷的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01

