HTTP是一種“無狀態”協議,這意味著每個客戶端檢索的網頁時,客戶端打開一個單獨的連接到Web服務器,服務器會自動以前的客戶端請求不保留任何記錄。
不過也有以下三種方式來維護Web客戶端和Web服務器之間的會話:
一個Web服務器可以分配一個唯一的會話ID作為一個cookie到每個Web客戶端和客戶端的後續請求可以確認接收的cookie。
這可能不是一個有效的方法,因為很多瀏覽器不支持cookie,所以我會建議不要使用這個程序來維護會話。
一個Web服務器可以發送一個隱藏的HTML表單字段,以及一個唯一的會話ID如下:
<input type="hidden" name="sessionid" value="12345">
該條目指的是,當表單被提交時,指定的名稱和值會被自動包含在GET或POST數據。每次當web瀏覽器發送請求發送回,然後session_id值可以用於保持不同的Web瀏覽器的軌跡。
這可能是一個有效的方法,跟蹤會話,但經常(<A HREF...>)超文本鏈接上單擊不會導致一個表單提交,因此隱藏的表單字段也可以不支持常規的會話跟蹤。
標識會話的每個URL的末尾,可以添加一些額外的數據和服務器相關聯的會話標識符與數據存儲有關該會話。
例如,http://tutorialspoint.com/file.htm;sessionid=12345,會話標識符sessionid= 12345可以訪問Web服務器,以確定客戶端連接。
URL重寫是一種更好的方式來維持會話可以工作在當他們不支持Cookie,但是缺點是,會產生每動態地分配一個會話ID到URL,即使是在很簡單的靜態HTML頁麵。
除了上述的三種方法,servlet提供了HttpSession接口提供了一個方法來識彆一個用戶跨多個頁麵請求或訪問一個網站,並存儲有關該用戶的信息。
使用這個接口,servlet容器創建一個HTTP客戶端和HTTP服務器之間的會話。會話持續一個指定的時間段,跨多個連接或頁麵請求用戶。
你會得到通過調用HttpSession對象的公共方法HttpServletRequest的getSession(),如下所示:
HttpSession session = request.getSession();
你需要調用request.getSession(),然後再發送任何文件的內容給客戶端。下麵是總結的HttpSession對象重要方法:
S.N. | 方法 & 描述 |
---|---|
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對象創建時間和最後訪問時間的會話信息。如果其中一個已經不存在了,我們為它創建一個新的會話相關聯的請求。
// Import required java libraries import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; // Extend HttpServlet class - by www.gitbook.net 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會話跟蹤,並在web.xml文件中創建相應的條目。現在運行http://localhost:8080/SessionTrack將顯示如下的結果時,你會第一次運行:
Session info | value |
---|---|
id | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
Creation Time | Tue Jun 08 17:26:40 GMT+04:00 2010 |
Time of Last Access | Tue Jun 08 17:26:40 GMT+04:00 2010 |
User ID | ABCD |
Number of visits | 0 |
現在嘗試運行相同的servlet第二遍,它會顯示下麵的結果。
info type | value |
---|---|
id | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
Creation Time | Tue Jun 08 17:26:40 GMT+04:00 2010 |
Time of Last Access | Tue Jun 08 17:26:40 GMT+04:00 2010 |
User ID | ABCD |
Number of visits | 1 |
當你完成了一個用戶的會話數據,你有幾種選擇:
刪除一個特定的屬性: 你可以調用pubic void removeAttribute(String name)方法刪除與特定的鍵關聯的值。
刪除整個會話: 你可以調用public void invalidate() 方法拋棄整個會話。
設置會話過期時間: 你可以調用 public void setMaxInactiveInterval(int interval) 方法來設置單獨的會話超時。
注銷用戶: 支持servlet2.4服務器,你可以調用注銷登錄客戶端的Web服務器,屬於所有用戶的所有會話無效。
web.xml 配置: 如果您使用的是Tomcat,除了上述方法,你可以配置會話超時在web.xml文件中如下。
<session-config> <session-timeout>15</session-timeout> </session-config>
在Tomcat中表示超時為分鐘,超時將被覆蓋默認的超時時間為30分鐘。
在一個servlet 的 getMaxInactiveInterval()方法返回的超時時間,會話在幾秒鐘內。所以,如果在web.xml中配置會話為15分鐘,那麼getMaxInactiveInterval()返回應該是900。