統計在線人數重復登錄 – JAVA編程語言程序開發技術文章

  <p style="text-align: left">防止web應用同一個賬戶重復登錄一般有一下兩種方式:
session實現
1.一個賬號登進去瞭,再用這個賬號就登不進去:
打開一個瀏覽器客戶端就有個sessionid與服務器對用,關閉後客戶端的沒瞭,但是服務端的還有這個session,
缺點:所以非法關閉的話,沒有調用session.invalidate()方法的話,這個session依然存在。隻有等到session過期,一般30分鐘。這樣用戶要等這麼長時間,肯定不好,所以盡可能的要捕捉非法關閉的事件,網上搜瞭,有些事件不好捕獲,如先最小化在關閉等。
2.一個賬號登進去瞭,再用這個賬號登進去,前一個session失效,提示賬戶已經在別處登錄。
缺點:如果也是非法關閉。用戶有沒有重新登錄,session沒有釋放,在線統計不太對,有點就是不影響用戶使用,可以繼續登進去使用。
所以選擇第二種:
struts2 
1.action裡的某個方法,
public void totalcount()
{        httpservletrequest request = servletactioncontext.getrequest();
   httpsession session = request.getsession();
                     //就是獲取用戶名,因為是struts2可以這樣獲取
   string username = user.getfirstname();
// 把用戶名放入在線列表
    map<string,string> onlineuserlist = (map<string,string>) servletactioncontext.getservletcontext().getattribute("onlineuserlist");
    // 第一次使用前,需要初始化
    if (onlineuserlist == null) {
        onlineuserlist = new hashmap<string,string>();
       
    }
//用戶名一樣,sessionid不一樣,所以是二次登錄        if(onlineuserlist.containskey(username) &amp;&amp; !(onlineuserlist.get(username).equals(session.getid())) )
   
    {  
    onlineuserlist.remove(username);

   
    }
    session.setattribute("username", username);
    onlineuserlist.put(username,session.getid());
   
    servletactioncontext.getservletcontext().setattribute("onlineuserlist", onlineuserlist);
 

}
2.listener,銷毀session,隻要調用session.invalidate()就會執行
public class userlistener implements httpsessionlistener {

    public void sessioncreated(httpsessionevent event) {
   
   
    }
    @suppresswarnings("unchecked")
    public void sessiondestroyed(httpsessionevent event) {
        httpsession session = event.getsession();   
       
        // 取得登錄的用戶名
            string username = (string) session.getattribute("username");
            servletcontext application = session.getservletcontext();
            system.out.println("listener開始");
            system.out.println("sessionid:"+session.getid());
            system.out.println("username:"+username);
            // 獲取在線列表
            map<string,string> onlineuserlist = (map<string,string>) application.getattribute("onlineuserlist");
            //session超時刪除用戶,重復登錄登錄時已刪除,不再刪瞭
            if(onlineuserlist.containskey(username) &amp;&amp; (onlineuserlist.get(username).equals(session.getid())) )
            {
            onlineuserlist.remove(username);
            servletactioncontext.getservletcontext().setattribute("onlineuserlist", onlineuserlist);
            }
            system.out.println("onlineuserlist:"+onlineuserlist);
            system.out.println("listener結束");

    }

}
3.filter
public class userfilter implements filter {
public void init(filterconfig config) throws servletexception {
}

public void destroy() {
}

@suppresswarnings("unchecked")
public void dofilter(servletrequest req, servletresponse res,
filterchain chain) throws ioexception, servletexception {

httpservletrequest request = (httpservletrequest) req;
httpservletresponse response = (httpservletresponse) res;
httpsession session = request.getsession();
system.out.println("過濾filter開始");
// 從servletcontext中取出list
map<string, string> sessionlist = (map<string, string>) session
.getservletcontext().getattribute("onlineuserlist");
system.out.println("sessionlist:" + sessionlist);
if (sessionlist == null) {
sessionlist = new hashmap<string, string>();
}

string username = (string) session.getattribute("username");
system.out.println("username:" + username);
system.out.println("sessionid:" + session.getid());
//因為過濾所有頁面web.xml配置的是/*,第一次登陸username為空,得讓可以登錄
if (null == username) {
chain.dofilter(req, res);
system.out.println("過濾filter結束username=null");

} else {
// 用於記錄狀態
boolean temp = false;
system.out.println(sessionlist.containskey(username));
system.out.println(sessionlist.get(username));
system.out.println(sessionlist.get(username)
.equals(session.getid()));
if (sessionlist.containskey(username)
&amp;&amp; sessionlist.get(username).equals(session.getid())) {
// session值與當前id匹配,說明同一個用戶
temp = true;

system.out.println("過濾filter結束,同一個用戶");
}
// 存在瞭第二次登陸,銷毀session
system.out.println("temp:" + temp);
if (!temp) {
session.invalidate();
response.setcharacterencoding("utf-8");
response.setcontenttype("text/html; charset=utf-8");
//轉向的首頁,根據自己項目
response
.getwriter()
.print(
"<script>window.top.location.href='/ssh2/save.jsp';alert('該賬號已經在別處登錄,請聯系管理員或關閉ie,重新登錄!');</script>");

} else {
chain.dofilter(req, res);
}

}

}

}

web.xml的配置。
filter放在struts2攔截器的前面
<filter>
<filter-name>userfilter</filter-name>
<filter-class>
com.test.action.user.userfilter
</filter-class>
</filter>
   

<filter-mapping>
<filter-name>userfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
listener的配置
調用session.invalide()的方法會被監聽到,銷毀session
<listener>                       
  <listener-class>com.test.action.user.userlistener</listener-class>
</listener>

大概實現瞭,可能考慮不周:如果有問題共同探討。

發佈留言