通常我們可以 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 失效
沒有留言:
張貼留言