
- JSP 基礎教程
- JSP - 首頁
- JSP - 概述
- JSP - 環境設定
- JSP - 架構
- JSP - 生命週期
- JSP - 語法
- JSP - 指令
- JSP - 動作
- JSP - 隱式物件
- JSP - 客戶端請求
- JSP - 伺服器響應
- JSP - HTTP 狀態碼
- JSP - 表單處理
- JSP - 編寫過濾器
- JSP - Cookie 處理
- JSP - 會話跟蹤
- JSP - 檔案上傳
- JSP - 處理日期
- JSP - 頁面重定向
- JSP - 點選計數器
- JSP - 自動重新整理
- JSP - 傳送電子郵件
- 高階 JSP 教程
- JSP - 標準標籤庫
- JSP - 資料庫訪問
- JSP - XML 資料
- JSP - JavaBean
- JSP - 自定義標籤
- JSP - 表示式語言
- JSP - 異常處理
- JSP - 除錯
- JSP - 安全性
- JSP - 國際化
- JSP 有用資源
- JSP - 問題與解答
- JSP - 快速指南
- JSP - 有用資源
- JSP - 討論
JSP - 會話跟蹤
在本章中,我們將討論 JSP 中的會話跟蹤。HTTP 是一種“無狀態”協議,這意味著每次客戶端檢索網頁時,客戶端都會開啟與 Web 伺服器的單獨連線,並且伺服器不會自動保留任何先前客戶端請求的記錄。
在 Web 客戶端和伺服器之間維護會話
現在讓我們討論一些在 Web 客戶端和 Web 伺服器之間維護會話的選項:
Cookie
Web 伺服器可以為每個 Web 客戶端分配一個唯一的會話 ID 作為 Cookie,並在客戶端的後續請求中使用接收到的 Cookie 進行識別。
這可能不是一種有效的方法,因為瀏覽器有時不支援 Cookie。不建議使用此過程來維護會話。
隱藏表單欄位
Web 伺服器可以傳送一個隱藏的 HTML 表單欄位,並附帶一個唯一的會話 ID,如下所示:
<input type = "hidden" name = "sessionid" value = "12345">
這意味著,當表單提交時,指定的名稱和值會自動包含在 **GET** 或 **POST** 資料中。每次 Web 瀏覽器傳送請求時,都可以使用 **session_id** 值來跟蹤不同的 Web 瀏覽器。
這可能是跟蹤會話的一種有效方法,但點選常規的 (<A HREF...>) 超文字連結不會導致表單提交,因此隱藏表單欄位也不能支援常規的會話跟蹤。
URL 重寫
您可以在每個 URL 的末尾附加一些額外的資料。這些資料標識會話;伺服器可以將該會話識別符號與其儲存的有關該會話的資料相關聯。
例如,對於 **https://tutorialspoint.tw/file.htm;sessionid=12345**,會話識別符號附加為 **sessionid = 12345**,Web 伺服器可以訪問它來識別客戶端。
URL 重寫是維護會話的一種更好的方法,並且在瀏覽器不支援 Cookie 時也能正常工作。這裡的缺點是您必須動態生成每個 URL 以分配會話 ID,即使頁面是一個簡單的靜態 HTML 頁面。
session 物件
除了上述選項外,JSP 還使用 servlet 提供的 HttpSession 介面。此介面提供了一種跨越以下範圍識別使用者的方法。
- 一個頁面請求或
- 訪問網站或
- 儲存有關該使用者的資訊
預設情況下,JSP 啟用了會話跟蹤,並且會為每個新的客戶端自動例項化一個新的 HttpSession 物件。停用會話跟蹤需要透過將頁面指令的 session 屬性顯式設定為 false 來關閉它,如下所示:
<%@ page session = "false" %>
JSP 引擎透過隱式 **session** 物件向 JSP 作者公開 HttpSession 物件。由於 **session** 物件已提供給 JSP 程式設計師,因此程式設計師可以立即開始從物件儲存和檢索資料,而無需任何初始化或 **getSession()**。
以下是透過 session 物件可用的重要方法的摘要:
序號 | 方法和描述 |
---|---|
1 |
public Object getAttribute(String name) 此方法返回在此會話中與指定名稱繫結的物件,如果在該名稱下沒有繫結任何物件,則返回 null。 |
2 |
public Enumeration getAttributeNames() 此方法返回一個 String 物件的 Enumeration,其中包含繫結到此會話的所有物件的名稱。 |
3 | public long getCreationTime() 此方法返回建立此會話的時間,以 1970 年 1 月 1 日午夜以來的毫秒數(格林威治標準時間)衡量。 |
4 | public String getId() 此方法返回一個包含分配給此會話的唯一識別符號的字串。 |
5 | public long getLastAccessedTime() 此方法返回客戶端上次傳送與此會話關聯的請求的時間,以 1970 年 1 月 1 日午夜以來的毫秒數(格林威治標準時間)衡量。 |
6 | public int getMaxInactiveInterval() 此方法返回 servlet 容器在客戶端訪問之間保持此會話開啟的最大時間間隔(以秒為單位)。 |
7 | public void invalidate() 此方法使此會話無效,並取消繫結與此會話繫結的任何物件。 |
8 | public boolean isNew() 如果客戶端尚不知道該會話或客戶端選擇不加入該會話,則此方法返回 true。 |
9 | public void removeAttribute(String name) 此方法從此會話中刪除與指定名稱繫結的物件。 |
10 | public void setAttribute(String name, Object value) 此方法使用指定的名稱將物件繫結到此會話。 |
11 | public void setMaxInactiveInterval(int interval) 此方法指定 servlet 容器在客戶端請求之間失效此會話之前的時間(以秒為單位)。 |
會話跟蹤示例
此示例說明如何使用 HttpSession 物件查詢會話的建立時間和上次訪問時間。如果不存在,我們將與請求關聯一個新會話。
<%@ page import = "java.io.*,java.util.*" %> <% // Get session creation time. Date createTime = new Date(session.getCreationTime()); // Get last access time of this Webpage. Date lastAccessTime = new Date(session.getLastAccessedTime()); String title = "Welcome Back to my website"; Integer visitCount = new Integer(0); String visitCountKey = new String("visitCount"); String userIDKey = new String("userID"); String userID = new String("ABCD"); // Check if this is new comer on your Webpage. if (session.isNew() ){ title = "Welcome to my website"; session.setAttribute(userIDKey, userID); session.setAttribute(visitCountKey, visitCount); } visitCount = (Integer)session.getAttribute(visitCountKey); visitCount = visitCount + 1; userID = (String)session.getAttribute(userIDKey); session.setAttribute(visitCountKey, visitCount); %> <html> <head> <title>Session Tracking</title> </head> <body> <center> <h1>Session Tracking</h1> </center> <table border = "1" align = "center"> <tr bgcolor = "#949494"> <th>Session info</th> <th>Value</th> </tr> <tr> <td>id</td> <td><% out.print( session.getId()); %></td> </tr> <tr> <td>Creation Time</td> <td><% out.print(createTime); %></td> </tr> <tr> <td>Time of Last Access</td> <td><% out.print(lastAccessTime); %></td> </tr> <tr> <td>User ID</td> <td><% out.print(userID); %></td> </tr> <tr> <td>Number of visits</td> <td><% out.print(visitCount); %></td> </tr> </table> </body> </html>
現在將上述程式碼放入 **main.jsp** 中,並嘗試訪問 **https://:8080/main.jsp**。執行 URL 後,您將收到以下結果:
歡迎訪問我的網站
會話資訊
會話資訊 | 值 |
---|---|
ID | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
建立時間 | 2010 年 6 月 8 日星期二 17:26:40 格林威治標準時間 +04:00 |
上次訪問時間 | 2010 年 6 月 8 日星期二 17:26:40 格林威治標準時間 +04:00 |
使用者 ID | ABCD |
訪問次數 | 0 |
現在嘗試第二次執行相同的 JSP,您將收到以下結果。
歡迎再次訪問我的網站
會話資訊
資訊型別 | 值 |
---|---|
ID | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
建立時間 | 2010 年 6 月 8 日星期二 17:26:40 格林威治標準時間 +04:00 |
上次訪問時間 | 2010 年 6 月 8 日星期二 17:26:40 格林威治標準時間 +04:00 |
使用者 ID | ABCD |
訪問次數 | 1 |
刪除會話資料
完成使用者會話資料後,您有幾個選項:
**刪除特定屬性** - 您可以呼叫 **public void removeAttribute(String name)** 方法刪除與特定鍵關聯的值。
**刪除整個會話** - 您可以呼叫 **public void invalidate()** 方法丟棄整個會話。
**設定會話超時** - 您可以呼叫 **public void setMaxInactiveInterval(int interval)** 方法單獨設定會話的超時時間。
**登出使用者** - 支援 servlet 2.4 的伺服器,您可以呼叫 **logout** 將客戶端登出 Web 伺服器並使屬於所有使用者的會話無效。
**web.xml 配置** - 如果您使用的是 Tomcat,除了上述方法外,您還可以如下在 web.xml 檔案中配置會話超時時間。
<session-config> <session-timeout>15</session-timeout> </session-config>
超時時間以分鐘為單位表示,並覆蓋 Tomcat 中的預設超時時間(30 分鐘)。
servlet 中的 **getMaxInactiveInterval( )** 方法以秒為單位返回該會話的超時時間。因此,如果您的會話在 web.xml 中配置為 15 分鐘,則 **getMaxInactiveInterval( )** 返回 900。