HTTP是“無狀態”協議:客戶程序每次讀取 Web 頁面,都打開到 Web 服務器的單獨的連接,並且,服務器也不自動維護客戶的上下文信息。即使那些支持持續性 HTTP 連接的服務器,盡管多個客戶請求連續發生且間隔很短時它們會保持 socket 打開,但是,它們也沒有提供維護上下文信息的內建支持。上下文的缺失引起許多困難。例如,在線商店的客戶向他們的購物車中加入商品時,服務器如何知道購物 車中己有何種物品呢?類似地,在客戶決定結賬時,服務器如何能確定之前創建的購物車中哪個屬於此客戶呢?這些問題雖然看起來十分簡單,但是由於 HTTP 的不足,解答它們卻異常復雜困難。對於這個問題,存在 3 種典型的解決方案:
Cookie(結合session使用)
可以使用 cookie 存儲購物會話的 ID;在后續連接中,取出當前的會話 ID,並使用這個 ID 從服務器上的查找表(lookup table)中提取出會話的相關信息。 以這種方式使用 cookie 是一種絕佳的解決方案,也是在處理會話時最常使用的方式。但是,sevlet 中最好有一種高級的 API 來處理所有這些任務,以及下面這些冗長乏味的任務:從眾多的其他cookie中(畢竟可能會存在許多cookie)提取出存儲會話標識符的 cookie;確定空閑會話什么時候過期,並回收它們;將散列表與每個請求關聯起來;生成惟一的會話標識符。
URL 重寫
采用這種方式時,客戶程序在每個URL的尾部添加一些額外數據。這些數據標識當前的會話,服務器將這個標識符與它存儲的用戶相關數據關聯起來。 URL重寫是比較不錯的會話跟蹤解決方案,即使瀏覽器不支持 cookie 或在用戶禁用 cookie 的情況下,這種方案也能夠工作。URL 重寫具有 cookie 所具有的同樣缺點,也就是說,服務器端程序要做許多簡單但是冗長乏味的處理任務。即使有高層的 API 可以處理大部分的細節,仍須十分小心每個引用你的站點的 URL ,以及那些返回給用戶的 URL。即使通過間接手段,比如服務器重定向中的 Location 字段,都要添加額外的信息。這種限制意味着,在你的站點上不能有任何靜態 HTML 頁面(至少靜態頁面中不能有任何鏈接到站點動態頁面的鏈接)。因此,每個頁面都必須使用 servlet 或 JSP 動態生成。即使所有的頁面都動態生成,如果用戶離開了會話並通過書簽或鏈接再次回來,會話的信息也會丟失,因為存儲下來的鏈接含有錯誤的標識信息。
隱藏的表單域
HTML 表單中可以含有如下的條目:<input type="hidden" name="session" value="a1234">
這個條目的意思是:在提交表單時,要將指定的名稱和值自動包括在 GET 或 POST 數據中。這個隱藏域可以用來存儲有關會話的信息,但它的主要缺點是:僅當每個頁面都是由表單提交而動態生成時,才能使用這種方法。單擊常規的超文本鏈接並 不產生表單提交,因此隱藏的表單域不能支持通常的會話跟蹤,只能用於一系列特定的操作中,比如在線商店的結賬過程。