會(huì)話跟蹤

2018-08-12 21:20 更新

會(huì)話跟蹤

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

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

Cookies

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

這可能不是一個(gè)有效的方法,因?yàn)楹芏鄷r(shí)候?yàn)g覽器不支持 cookie,所以我不建議使用這種方式來維持會(huì)話。

隱藏的表單字段

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

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

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

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

URL 重寫

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

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

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

HttpSession 對(duì)象

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

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

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

HttpSession session = request.getSession();

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

序號(hào) 方法 & 描述
1

public Object getAttribute(String name)

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

2

public Enumeration getAttributeNames()

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

3

public long getCreationTime()

該方法返回該 session 會(huì)話被創(chuàng)建的時(shí)間,自格林尼治標(biāo)準(zhǔn)時(shí)間 1970 年 1 月 1 日凌晨零點(diǎn)算起,以毫秒為單位。

4

public String getId()

該方法返回一個(gè)包含分配給該 session 會(huì)話的唯一標(biāo)識(shí)符的字符串。

5

public long getLastAccessedTime()

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

6

public int getMaxInactiveInterval()

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

7

public void invalidate()

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

8

public boolean isNew(

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

9

public void removeAttribute(String name)

該方法將從該 session 會(huì)話移除指定名稱的對(duì)象。

10

public void setAttribute(String name, Object value)

該方法使用指定的名稱綁定一個(gè)對(duì)象到該 session 會(huì)話。

11

public void setMaxInactiveInterval(int interval)

該方法在 Servlet 容器指示該 session 會(huì)話無效之前,指定客戶端請(qǐng)求之間的時(shí)間,以秒為單位。

會(huì)話跟蹤實(shí)例

這個(gè)例子描述了如何使用 HttpSession 對(duì)象獲取會(huì)話創(chuàng)建時(shí)間和上次訪問的時(shí)間。如果不存在會(huì)話,我們將一個(gè)新的會(huì)話與請(qǐ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)建適當(dāng)?shù)臈l目。在瀏覽器地址欄輸入 http://localhost:8080/SessionTrack,當(dāng)你第一次運(yùn)行時(shí)將顯示如下所示的結(jié)果:


Welcome to my website

Session Infomation

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


Welcome Back to my website

Session Infomation

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

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

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

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

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

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

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

超時(shí)時(shí)間是以分鐘為單位的,并覆蓋了 Tomcat 中默認(rèn)的 30 分鐘的超時(shí)時(shí)間。

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

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)