2011年2月12日 星期六

【Java WEB】HttpSessionBindingListener 實現用戶監控

HttpSessionBindingListener 為一個在 javax.servlet.http 的監聽器

通常我們可以 HttpSessionBindingListener 來監控用戶的在線狀態

而 HttpSessionBindingListener 的運用即是架構在 HttpSession 的屬性的繫結(binding)與釋放(unbinding),且運用 HttpSessionBindingListener 不必再 web.xml 中註冊監聽器

以下以一個 UserInfo 類別來保存所有上線的使用者
package com.model;
import java.util.Vector;
public class UserInfo 
{
    /** 這裡採用一個靜態變數 使得每個 UserInfo 都擁有, 即所有的加入和移除用戶都是透過此 靜態變數**/
    private static UserInfo user = new UserInfo();
    private Vector list = null;
    public UserInfo(){
        this.list = new Vector();
    }
    public static UserInfo getInstance(){  //取得該靜態變數 UserInfo 
        return user;
    }
    public boolean addUser(String user){   //加入一個用戶  代表上線
        if(user != null){
            this.list.add(user);
            return true;
        }else{
            return false;
        }
    }
    public Vector getList(){   
        return this.list;
    }
    public void removeUser(String user){    //移除某一個線上用戶  代表下線
        if(user != null){
            this.list.removeElement(user);
        }
    }
}


接下來來看一個 UserSessionBinding 的類別並實作 javax.servlet.http.HttpSessionBindingListener

package com.listener;
import com.model.UserInfo;
import javax.servlet.http.HttpSessionBindingEvent;
public class UserSessionBinding implements javax.servlet.http.HttpSessionBindingListener
{
    private String username;
    private UserInfo ui = UserInfo.getInstance();
    public UserSessionBinding(){
        this.username =  "";
    }
    public void setUsername(String username){
        this.username = username;
    }
    public String getUsername(){
        return this.username;
    }
    public void valueBound(HttpSessionBindingEvent arg0) {   //必須實做此方法 代表屬性被繫結
        System.out.println("上線用戶 : " + this.username);
    }
    public void valueUnbound(HttpSessionBindingEvent arg0) {  //必須實做此方法  
        System.out.println("下線用戶 : " + this.username);
        if(this.username != ""){
            ui.removeUser(username);    //移除該上線用戶
        } 
    }
}


以上記得的是 implements javax.servlet.http.HttpSessionBindingListener

必須實做 valueBound() 和 valueUnbound() 這兩個方法

最後來觀察如何實現用戶上線和下線

//... 某個 Servlet 中

String username = request.getParameter("username");
HttpSession session = request.getSession();  //取得 HttpSession
session.setMaxInactiveInterval(120);   //設定其過期的時限為 2分鐘
UserInfo user = UserInfo.getInstance();
Vector list = user.getList();    //取得存放所有用戶的 Vector
UserSessionBinding usb = new UserSessionBinding();
usb.setUsername(username);
user.addUser(username);   //加入至 list
session.setAttribute("user", usb);   //此處發生 binding


以上的試驗結果在

IE 瀏覽器中

如果開了一個分頁登入了使用者 AAA 此時 Console 會打印出 "上線用戶 : AAA"

如果再打開另一個分頁(不是另一個IE browser) 登入使用者 BBB

此時 Console 會打印出 "上線用戶 : BBB" 和 "下線用戶 : AAA"

而如果是開了兩個 IE 瀏覽器的話,則 AAA 就不會被擠下去 因為同一個視窗內的 browser 是同一個 session

而不同的 IE 視窗則是不同的 session

至於在 chrome 中測試的話

則是不論是分頁或是多個瀏覽器 均為同一個 session

至於如果使用者點即登出之類的

則直接以 session 的 invalidate() 方法讓該 session 失效

沒有留言:

張貼留言