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。

廣告