會話跟蹤

2018-08-12 21:20 更新

會話跟蹤

HTTP 是一種“無狀態(tài)”協(xié)議,這意味著每次客戶端檢索 Web 頁面時,客戶端打開一個單獨的連接到 Web 服務(wù)器,服務(wù)器不會自動保存之前客戶端請求的任何記錄。

仍然有以下三種方式來維持 web 客戶端和 web 服務(wù)器之間的會話:

Cookies

一個 web 服務(wù)器可以分配一個唯一的會話 ID 作為每個 web 客戶端的 cookie,并且對于來自客戶端的后續(xù)請求,它們可以使用已接收的 cookie 來識別。

這可能不是一個有效的方法,因為很多時候瀏覽器不支持 cookie,所以我不建議使用這種方式來維持會話。

隱藏的表單字段

一個 web 服務(wù)器可以發(fā)送一個隱藏的 HTML 表單字段以及一個唯一的會話 ID,如下所示:

<input type="hidden" name="sessionid" value="12345">

該條目意味著,當表單被提交時,指定的名稱和值會被自動包含在 GET 或 POST 數(shù)據(jù)中。每次當 web 瀏覽器發(fā)送回請求時,session_id 的值可以用于跟蹤不同的 web 瀏覽器。

這可能是保持會話跟蹤的一種有效的方式,但是點擊常規(guī)的(<A HREF...>)超文本鏈接不會導致表單提交,因此隱藏的表單字段也不支持常規(guī)的會話跟蹤。

URL 重寫

你可以在每個標識會話的 URL 末尾追加一些額外的數(shù)據(jù),且服務(wù)器會把該會話標識符與它已存儲的有關(guān)會話的數(shù)據(jù)關(guān)聯(lián)起來。

例如,http://w3cschool.cn/file.htm;sessionid=12345,會話標識符被附加為 sessionid=12345,可能會在 web 服務(wù)器端被訪問來識別客戶端。

URL 重寫是維持會話的一種更好的方式,當瀏覽器不支持 cookie 時為瀏覽器工作,但是它的缺點是會動態(tài)的生成每個 URL 來分配會話 ID,即使頁面是簡單的靜態(tài)的 HTML 頁面。

HttpSession 對象

除了上述提到的三種方式,servlet 還提供了 HttpSession 接口,該接口提供了一種對網(wǎng)站的跨多個頁面請求或訪問的方法來識別用戶并存儲有關(guān)用戶的信息。

Servlet 容器使用這個接口來創(chuàng)建在 HTTP 客戶端和 HTTP 服務(wù)器之間的會話。會話在一個指定的時間段內(nèi)持續(xù),跨多個連接或來自用戶的請求。

你可以通過調(diào)用 HttpServletRequest 的公共方法 getSession() 來獲取 HttpSession 對象,如下所示:

HttpSession session = request.getSession();

在向客戶端發(fā)送任何文檔內(nèi)容之前,你需要調(diào)用 request.getSession()。這里是一些重要方法的總結(jié),這些方法通過 HttpSession 對象是可用的:

序號 方法 & 描述
1

public Object getAttribute(String name)

該方法返回在該 session 會話中具有指定名稱的對象,如果沒有指定名稱的對象,則返回 null。

2

public Enumeration getAttributeNames()

該方法返回 String 對象的枚舉,String 對象包含所有綁定到該 session 會話的對象的名稱。

3

public long getCreationTime()

該方法返回該 session 會話被創(chuàng)建的時間,自格林尼治標準時間 1970 年 1 月 1 日凌晨零點算起,以毫秒為單位。

4

public String getId()

該方法返回一個包含分配給該 session 會話的唯一標識符的字符串。

5

public long getLastAccessedTime()

該方法返回客戶端最后一次發(fā)送與該 session 會話相關(guān)的請求的時間自格林尼治標準時間 1970 年 1 月 1 日凌晨零點算起,以毫秒為單位。

6

public int getMaxInactiveInterval()

該方法返回 Servlet 容器在客戶端訪問時保持 session 會話打開的最大時間間隔,以秒為單位。

7

public void invalidate()

該方法指示該 session 會話無效,并解除綁定到它上面的任何對象。

8

public boolean isNew(

如果客戶端還不知道該 session 會話,或者如果客戶選擇不參入該 session 會話,則該方法返回 true。

9

public void removeAttribute(String name)

該方法將從該 session 會話移除指定名稱的對象。

10

public void setAttribute(String name, Object value)

該方法使用指定的名稱綁定一個對象到該 session 會話。

11

public void setMaxInactiveInterval(int interval)

該方法在 Servlet 容器指示該 session 會話無效之前,指定客戶端請求之間的時間,以秒為單位。

會話跟蹤實例

這個例子描述了如何使用 HttpSession 對象獲取會話創(chuàng)建時間和上次訪問的時間。如果不存在會話,我們將一個新的會話與請求聯(lián)系起來。

// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*; 
// Extend HttpServlet class
public class SessionTrack extends HttpServlet { 
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      // Create a session object if it is already not  created.
      HttpSession session = request.getSession(true);
      // Get session creation time.
      Date createTime = new Date(session.getCreationTime());
      // Get last access time of this web page.
      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 web page.
      if (session.isNew()){
         title = "Welcome to my website";
         session.setAttribute(userIDKey, userID);
      } else {
         visitCount = (Integer)session.getAttribute(visitCountKey);
         visitCount = visitCount + 1;
         userID = (String)session.getAttribute(userIDKey);
      }
      session.setAttribute(visitCountKey,  visitCount);
      // Set response content type
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      String docType =
      "<!doctype html public \"-//w3c//dtd html 4.0 " +
      "transitional//en\">\n";
      out.println(docType +
                "<html>\n" +
                "<head><title>" + title + "</title></head>\n" +
                "<body bgcolor=\"#f0f0f0\">\n" +
                "<h1 align=\"center\">" + title + "</h1>\n" +
                 "<h2 align=\"center\">Session Infomation</h2>\n" +
                "<table border=\"1\" align=\"center\">\n" +
                "<tr bgcolor=\"#949494\">\n" +
                "  <th>Session info</th><th>value</th></tr>\n" +
                "<tr>\n" +
                "  <td>id</td>\n" +
                "  <td>" + session.getId() + "</td></tr>\n" +
                "<tr>\n" +
                "  <td>Creation Time</td>\n" +
                "  <td>" + createTime + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>Time of Last Access</td>\n" +
                "  <td>" + lastAccessTime + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>User ID</td>\n" +
                "  <td>" + userID + 
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>Number of visits</td>\n" +
                "  <td>" + visitCount + "</td></tr>\n" +
                "</table>\n" +
                "</body></html>");
  }
}

編譯上述 servlet SessionTrack 并在 web.xml 文件中創(chuàng)建適當?shù)臈l目。在瀏覽器地址欄輸入 http://localhost:8080/SessionTrack,當你第一次運行時將顯示如下所示的結(jié)果:


Welcome to my website

Session Infomation

現(xiàn)在嘗試再次運行相同的 servlet,它將顯示如下所示的結(jié)果:


Welcome Back to my website

Session Infomation

刪除會話數(shù)據(jù)

當你完成了一個用戶的會話數(shù)據(jù),你有以下幾種選擇:

  • 移除一個特定的屬性:你可以調(diào)用 public void removeAttribute(String name) 方法來刪除與特定的鍵相關(guān)聯(lián)的值。

  • 刪除整個會話:你可以調(diào)用 public void invalidate() 方法來刪除整個會話。

  • 設(shè)置會話超時:你可以調(diào)用 public void setMaxInactiveInterval(int interval) 方法來單獨設(shè)置會話超時。

  • 注銷用戶:支持 servlet 2.4 的服務(wù)器,你可以調(diào)用 logout 來注銷 Web 服務(wù)器的客戶端,并把屬于所有用戶的所有會話設(shè)置為無效。

  • web.xml 配置:如果你使用的是 Tomcat,除了上述方法,你還可以在 web.xml 文件中配置會話超時,如下所示:
<session-config>
    <session-timeout>15</session-timeout>
  </session-config>

超時時間是以分鐘為單位的,并覆蓋了 Tomcat 中默認的 30 分鐘的超時時間。

Servlet 中的 getMaxInactiveInterval() 方法為會話返回的超時時間是以秒為單位的。所以如果在 web.xml 中配置會話超時時間為 15 分鐘,那么 getMaxInactiveInterval() 會返回 900。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號