會話跟蹤技術


1 會話跟蹤技術

在Servlet規范中,有以下三種機制用於會話跟蹤:

1) SSL(安全套接字層)會話:

  一種加密技術,主要原理是采用SSL的服務器和客戶端之間產生會話密鑰,建立一種加密的連接會話。

2) Cookies:

  是最常用的跟蹤用戶會話的方式,Cookie是一種由服務器發送給客戶的片段信息,存儲在客戶端瀏覽器的內存或硬盤上,客戶端在發起請求時攜帶此信息最為用戶的唯一標識。

Cookie以鍵值對的方式記錄會話跟蹤的內容,服務器利用響應報頭Set-Cookie來發送Cookie信息。在RFC2109中定義的Set-Cookie響應報頭的格式為:

Set-Cookie: NAME=VALUE ; Comment=value ; Domain=value ; Max-Age=value ; Path=value ; Secure ; Version=1*DIGIT

NAME是Cookie的名字,VALUE是Cookie的值。NAME=VALUE 屬性-值對必須首先出現,在此之后的屬性-值對可以任何順序出現。在Servlet規范中,用於會話跟蹤的Cookie的名字必須是JSESSIONID。

Comment屬性可選,因為Cookie可能包含關於用戶的私有信息,這個屬性允許服務器說明這個Cookie的使用,用戶可以檢查這個信息,然后決定是否加入或者繼續會話。

Domain是可選屬性,用於指定Cookie在哪一個域中有效,所指定的域必須以點號(.)開始。

Max-Age屬性是可選的,用於定義Cookie的生存時間,以秒為單位,如果超過了這個時間,客戶端應該丟棄這個Cookie,當然如果指定的秒數為0,表示立即丟棄這個Cookie,即客戶端不保存此Cookie。

Path屬性是可選的,用於指定這個Cookie在哪一個URL子集下有效。

Secure屬性也是可選,它沒有值,用於指示瀏覽器使用安全的方式與服務器交互。

Version屬性是必需的,它的值是一個十進制的整數,標識Cookie依照的狀態管理規范的版本。

舉例:

Set-Cookie: uid=zhen; Domain=.hzw.org ; Max-Age=3600 ; Path=/zwbg; Version=1

以上這個響應報頭發送了一個名為uid,值為zhen的Cookie,Cookie的存活時間是3600秒,在hzw.org域的/zwbg路徑下有效,在3600秒后,瀏覽器會丟棄這個Cookie。

在瀏覽器收到這個響應報頭后,可以選擇拒絕或者接受這個Cookie,如果瀏覽器接受這個Cookie,當瀏覽器下一次發送請求給http://www.hzw.org/zwbg/路徑下的資源時,同時也會發送下面的請求報頭: Cookie:uid=zhen  ,服務器從請求報頭中得到Cookie,然后通過標識取出在服務器中存儲的zhen的狀態信息,通過為不同的用戶發送不同的Cookie,就可以實現每個用戶的會話跟蹤。

因為Cookie是在響應報頭和請求報頭中被傳送的,不與傳送的內容混淆,所以Cookie的使用對於用戶來說是透明的。然而正是因為Cookie對用戶是透明的,加上Cookie的持久性高,可以長時間的追蹤用戶(Cookie可以保存在用戶的硬盤里),了解用戶的上網習慣,造成一些隱私權和安全方面的問題,於是有些用戶在使用瀏覽器時會禁用Cookie,這樣的話,web服務器就不能利用Cookie來跟蹤用戶的會話了,要解決這個問題,可以使用下面要講的URL重寫機制。

3)URL重寫

  當客戶端不接受Cookie的時候,可以使用URL重寫的機制來跟蹤用戶的會話。

URL重寫就是在URL中附加標識客戶的sessionID,Servlet容器解釋URL,取出SessionID,根據SessionID就可以將請求和特定的Session關聯。

sessionID被編碼為URL字符串中的路徑參數,在Servlet規范中,這個參數的名字必須是jsessionid,下面是一個包含了編碼后的路徑信息的URL的例子:

http://www.hzw.org/zwbg/index.jsp;jsessionid=1234

還可以在后面加上查詢字符串,完整的URL為:

http://www.hzw.org/zwbg/index.jsp;jsessionid=1234?name=zhen&age=18

服務器將sessionID作為URL的一部分發送給客戶端,客戶端在請求URL中再傳回來,這樣服務器就可以跟蹤用戶的會話了。

要跟蹤客戶端的會話,就必需將所有發往客戶端的URL進行編碼,這可以通過調用HttpServletResponse接口中的encodeURL()方法和encodeRedirectURL()方法來實現。其中encodeRedirectURL()方法主要在sendRedirec()方法調用之前使用,用於編碼重定向的URL。


 

2 Servlet API的會話跟蹤

在java Servlet API中,javax.servlet.http.HttpSession接口封裝了Session的概念,Servlet容器提供了這個接口的實現。當請求一個會話時,Servlet容器就創建一個HttpSession對象,有了這個對象之后,就可以利用這個對象保存客戶的狀態信息。

比如,購物車,Servlet容器為HttpSession對象分配一個唯一的SessionID,將其作為Cookie(或者作為URL的一部分,利用URL重寫機制)發送給瀏覽器,瀏覽器在內存中保存這個Cookie。當客戶再次發送HTTP請求時,瀏覽器將Cookie隨請求一起發送,Servlet容器從請求對象中獲取SessionID,然后根據SessionID找到對應的HttpSession對象,從而得到客戶的狀態信息。

整個會話過程對於開發和用戶來說都是透明的(由Servlet容器完成),開發人員只需得到HttpSession對象,然后調用這個對象的setAttribute()或者getAttribute()方法來保存獲取讀取客戶的狀態信息。整個會話跟蹤過程如圖:


 1)HttpSession接口:

方法:

這四個方法是在HttpSession對象中讀取、移除和設置屬性,利用這些方法,可以在Session中維護客戶的狀態信息

public abstract Object getAttribute(String s);

public abstract Enumeration getAttributeNames();

public abstract void setAttribute(String s, Object obj);

public abstract void removeAttribute(String s);

 

public abstract long getCreationTime(); 返回Session的創建時間,這個時間是從1970年1月1日00:00:00GMT以來的毫秒數

public abstract String getId(); 返回一個字符串,其中包含了分配給Session的唯一標識符,這個標識符是由Servlet容器分配的,與具體的實現沒關

public abstract long getLastAccessedTime(); 返回客戶端最后一次發送與Session相關請求的時間,這個時間是從1970年1月1日00:00:00GMT以來的毫秒數。這個方法可以用來確定客戶端在兩次請求之間會話的非活動時間。

 

public abstract void setMaxInactiveInterval(int i);設置在Session失效之前,客戶端的兩個連續請求之間的最大時間間隔,如果設置一個負值,表示session永遠不會失效,web應用程序可以使用該方法來設置Session的超時時間間隔。

public abstract int getMaxInactiveInterval();返回以毫秒為單位的最大的時間間隔。這個時間間隔值是Servlet容器在客戶的兩次連續請求之間保持Session打開的最大時間間隔,超過這個時間間隔,Servlet容器就使Session失效。

 

public abstract void invalidate();

  這個方法使會話失效,例如在網上書店購買完圖書后,就可以選擇退出登錄,服務器端的web應用程序可以調用這個方法是Session失效,從而讓用戶不再與這個Session關聯

public abstract boolean isNew();

  如果客戶端還不知道這個Session或者客戶端沒有選擇加入Session,那么這個方法將返回true。例如服務器使用基於Cookie的Session,而客戶端禁用了Cookie,那么對於每一個請求,Session都是新的。

  要得到一個Session對象,可以調用HttpServletRequest接口的getSession()方法:

  1)public HttpSession getSession();該方法返回與此請求相關聯的Session,如果沒有給用戶分配Session,則會創建一個新的Session

  2)public HttpSession getSession(boolean create)該方法返回與請求相關聯的Session,如果沒有給客戶分配Session,而create參數為true,則會創建一個新的Session,如果create參數為false,而此請求沒有一個有效的HttpSession,則返回null


public abstract ServletContext getServletContext();

  返回Session所屬的ServletContext對象


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM