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