JSP作為伺服器端編程的後起之秀,其佔據重要地位與良好的行業標準支持密不可分。Session機制正是JSP提供的核心基礎設施之一,它讓開發者無需關心客戶端具體實現,即可輕鬆構建基於會話的用戶管理體系。針對在線用戶的統計與管理,業界主要存在兩種主流處理模式。
此模式下,頁面刷新由用戶主動觸發,服務端設置固定超時時間(如30分鐘)。若用戶在該時段內無任何操作,系統將自動終止會話並踢出用戶。優勢在於能有效防止用戶忘記退出導致的惡意操作風險;劣勢則是當用戶執行耗時任務超過超時限制時,提交數據可能面臨重新登錄,甚至導致未保存的工作丟失。從實現角度看,這是最簡單的方案,也是Servlet容器的默認行為。
採用框架結構的站點(如xici.net),通常在隱藏的iframe或Frame中設置定時刷新機制,使會話永不超時。服務端需定義「發呆時間」:若用戶超過該時長僅有自動刷新頁面而無實際業務操作,則判定為離線。此模式優勢在於可利用持續刷新實現類Server-push功能,如即時消息推送。
無論採用哪種模式,要實現「瀏覽當前所有在線用戶」功能,都需額外開發工作。Servlet API本身未提供獲取Session列表的接口,但可利用監聽器機制實現。Servlet 2.2與2.3規範在這方面略有差異:2.2版提供HttpSessionBindingListener,可在Session屬性變更時通知相關類;2.3版新增HttpSessionAttributeListener。考慮到早期開發環境(如Visual Age for Java 4、JRun 3.1)多不直接支持Servlet 2.3,本文以HttpSessionBindingListener為例說明實現思路。
需創建實現HttpSessionBindingListener接口的類,該接口定義兩個回調方法:
public void valueBound(HttpSessionBindingEvent event)
public void valueUnbound(HttpSessionBindingEvent event)
當執行Session.addAttribute(String, Object)且被添加的對象實現了該接口時,容器將調用valueBound;反之,Session.removeAttribute觸發valueUnbound。
以下是具體實現示例,利用ServletContext全局存儲活躍Session集合:
public class HttpSessionBinding implements javax.servlet.http.HttpSessionBindingListener {
ServletContext application = null;
public HttpSessionBinding(ServletContext application) {
super();
if (application == null)
throw new IllegalArgumentException("Null application is not accept.");
this.application = application;
}
public void valueBound(javax.servlet.http.HttpSessionBindingEvent e) {
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions == null) {
activeSessions = new Vector();
}
JDBCUser sessionUser = (JDBCUser) e.getSession().getAttribute("user");
if (sessionUser != null) {
activeSessions.add(e.getSession());
}
application.setAttribute("activeSessions", activeSessions);
}
public void valueUnbound(javax.servlet.http.HttpSessionBindingEvent e) {
JDBCUser sessionUser = (JDBCUser) e.getSession().getAttribute("user");
if (sessionUser == null) {
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions != null) {
activeSessions.remove(e.getSession().getId());
application.setAttribute("activeSessions", activeSessions);
}
}
}
}
此方案通過監聽Session屬性綁定/解綁事件,在應用上下文中維護一個動態更新的在線用戶Session集合,從而實現高效的在線用戶統計與展示。