1:會話和會話跟蹤
Session在中文中常被翻譯為“會話”,原意是指自始至終的壹系列動作或消息。例如,從拿起電話撥號到掛斷電話的壹系列過程可以稱為壹個會話。有時妳可以看到“在瀏覽器會話期間…”的字樣,這裏的“會話”壹詞使用的是它的本義,指的是從瀏覽器窗口打開到關閉的這段時間;如果我們說“用戶在對話中……”,指的是用戶的壹系列動作,比如網購從登錄到購買商品再到結賬的過程;然而,有時它可能只是指壹種聯系。Session有很多意思,區別只能從上下文推斷。會話跟蹤是指壹種保持客戶端和服務器之間狀態的解決方案。簡單來說,當客戶在多個頁面之間切換時,服務器會保存用戶的信息。
2.實現會話跟蹤的四種方法實現會話跟蹤有四種方法:
(1)使用永久cookies。
(2)用額外的參數重寫URL。
(3)創建壹個包含數據的隱藏表單域。
(4)使用內置的session對象。
會話跟蹤的前三種方法是傳統的,每種方法都有其缺點。最後壹種方法是目前最常用也是最有效的解決方案,這裏重點介紹第四種會話跟蹤方法。然而,為了徹底理解會話跟蹤的機制,我們應該首先介紹傳統的會話跟蹤方法。(和我這裏的理解不太壹樣。我把我的理解記錄下來。Java Servlet規範中規定了會話的機制,tomcat容器實現了這壹規定。tomcat是通過cookie和url重寫的方式實現的。也就是說,通過cookie或者url重寫保存壹個會話ID,讓tomcat在內部把這個會話ID和壹個映射關聯起來,達到把變量和會話關聯起來的目的。因此,第壹種和第二種方法是tomcat或其他servlet容器實現會話機制的手段,但我們也可以自己實現。第三種方法只是兩個頁面跳轉時傳遞變量的壹種方式。以這種方式實現會話機制是不現實的。有必要在每壹頁上寫下隱藏的數據和所有要傳遞的變量。)
2.1:使用Cookie
Cookie是壹個很小的文本文件,記錄了這個文本文件中的會話信息,每個頁面都從Cookie中提取了之前的會話信息。例如:
string session id = make uniquestring();
HashMap session info = new HashMap();
HashMap global table = findTableStoringSessions();
globalTable.put(sessionID,session info);
Cookie session Cookie = new Cookie(" JSESSIONID ",session id);
session cookie . set path("/");
response . add cookie(session cookie);
上面的代碼首先在HashMap中記錄會話信息,保存在服務器端,用sessionID標識,然後將sessionID保存在壹個名為“jssessionid”的Cookie中。
cookie[]cookie = request . get cookies();
String sessionid = null
HashMap sessionInfo = null
HashMap global table = findTableStoringSessions();
如果(餅幹!=null){
for(int I = 0;我& ltcookies.lengthi++){
if(cookies[i]。getName()。equals(" JSESSIONID "){
session id = cookie[I]。getValue();
打破;
}
}
if(sessionid!=null){
session info = global table . get(session id);
//我們可以使用sessionInfo來獲取我們想要的值
}
}
用戶的請求到達服務器後,首先從Cookie中提取sessionID,然後從HashMap中提取會話信息。因此,實現了會話跟蹤。
雖然cookies功能強大且持久,但有些用戶會因為擔心cookies對個人隱私的威脅而關閉cookies。壹旦發生這種情況,他們就無法使用cookies來實現會話跟蹤的功能。
2.2:URL重寫
URL重寫是利用GET的方法在URL的末尾添加壹些額外的參數,達到會話跟蹤的目的。服務器將該標識符與存儲的關於會話的數據相關聯。URL看起來像這樣:
http://host/path/file . html;jsessionid=1234,
使用URL重寫的優點是Cookie在被禁用或根本不支持時仍然可以工作。但是也有很多缺點:
1.所有指向妳的網站的網址必須編碼。
2.所有頁面必須動態生成。
3.您不能使用預先錄制的網址訪問,或從其他網站鏈接訪問。
2.3:隱藏表單字段
隱藏表單字段的方法是利用HTML中的hidden屬性,在用戶不知情的情況下,將客戶端的信息偷偷發送給服務器,與請求壹起處理,從而可以進行會話跟蹤的任務。您可以通過以下方式對隱藏的表單域進行會話跟蹤。
& ltinput type = " hidden " name = " userID " value = " 15 " >
然後,通過隱藏字段將重要的用戶信息(如ID等唯壹數據)傳輸到服務器。隱藏字段的優點是,當會話數據傳輸到服務器時,與GET方法不同,會話數據將在URL上公開。但是這種方法還是有其缺點:壹旦會話數據存儲在隱藏字段中,仍然存在暴露數據的風險,因為只要用戶直接觀看HTML的源文件,會話數據就會被暴露。這會造成安全漏洞,尤其是依靠用戶ID和密碼獲取用戶數據,會有被竊取的危險。另外,這種方法只適用於特定的進程,不適合通常意義上的會話跟蹤。
2.4:使用內置會話對象
傳統的會話跟蹤方法使用起來比較麻煩,而Servlet的會話機制是基於Cookie或者URL重寫技術,結合了這兩種技術的優點。當客戶端允許使用cookie時,內置的會話對象使用cookie進行會話跟蹤;如果客戶端禁用Cookie,請選擇使用URL重寫。
(1)獲取會話對象。例如,將購物車作為屬性存儲在會話中,並且可以通過會話在其他JSP頁面中獲取購物車。
//session可以直接在JSP頁面中使用。
shopping cart cart =(shopping cart)session . get attribute(" cart ");
內置會話對象是javax的壹個實例。Servlet.http.HttpSession類。如果您在JavaBean或servlet中使用會話,您需要首先從當前請求對象中獲取它,例如:
//獲取用戶會話和購物籃。
http session session = request . getsession();
shopping cart cart =(shopping cart)session . get attribute(" cart ");
(2)讀寫會話中的數據,使用setAttribute方法保存會話中的對象,通過getAttribute方法讀取對象。從會話返回的值應該被轉換成適當的類型,並且應該檢查結果是否為空。例如,下面的代碼:
http session session = request . getsession();
some class value =(some class)session . get attribute(" some id ");
if (value == null) {
value =新的SomeClass(...);
session.setAttribute("someID ",value);
}
doSomethingWith(值);
(3)丟棄會話數據調用removeAttribute丟棄會話中的值,即刪除與名稱關聯的值。
調用invalidate放棄整個會話,即放棄當前會話。
如果用戶註銷並離開站點,請小心丟棄與該用戶相關的所有會話。
(4)會話的生命周期因為沒有辦法知道壹個HTTP客戶端是否不再需要壹個會話,所以每個會話都與壹個時間限制相關聯,以便其資源可以被回收。setMaxInactiveInterval(int secondsToLive)
(5)當服務器使用會話時,默認使用Cookie技術進行會話跟蹤。通常,會話管理意味著服務器將會話ID作為cookie存儲在用戶的Web瀏覽器中,並使用它來唯壹地標識每個用戶的會話。如果客戶端不接受Cookie,服務器可以使用URL重寫將sessionID作為參數附加到URL上,實現會話管理。
當我們forward,redirect時,我們必須調用以下兩個方法來保持會話有效(如果我們不調用它,當妳到達新頁面時,會話將無效,因為會話id尚未被傳遞)。
Servlet中的接口HttpServletResponse指定了兩個方法,即response.encodeURL()或response.encodeRedirectURL()。這兩種方法首先確定瀏覽器是否支持Cookies如果支持,參數URL原樣返回,會話ID會通過Cookies維護;否則,返回帶有sessionID的URL。Tomcat服務器實現了這兩種方法。
下面是壹個使用encodeURL方法的例子,兩個文件,hello1.jsp和hello2.jsp。
答:hello1.jsp完整的程序代碼如下:
& lt%@頁content type = " text/html;charset=gb2312"% >
& lt% String URL = response . encode URL(" hello 2 . JSP ");% & gt
& lta href = ' & lt% = url % & gt'& gt去hello2.jsp
乙:解釋:
Hello1.jsp使用響應對象中的encodeURL方法對URL進行編碼。這裏編碼不是重點,重點是如果瀏覽器的cookie被禁用了,就那樣了;jssession id = a09f 3a 5583825 ee 787580106 CCC 62 a 1 E8這樣的字符串會加在hello2.jsp的後面,它告訴下壹個頁面會話的信息。
b:使用重定向,例如:
response . send redirect(" hello 2 . JSP ");還應該改成:response . send redirect(response . encoder redirection(" hello 2 . JSP "));同時需要註意的是,當會話的ID用URL編碼時,每壹個頁面都需要進行編碼來保存會話的ID。如果遇到未編碼的URL,則無法跟蹤會話。
c:hello2.jsp完整的程序代碼如下:
& lt%@頁content type = " text/html;charset=gb2312"% >
& lt% out . println(" session id is "+session . getid());% & gt
d:您可以看到,如果服務器使用URL重寫,它會將會話信息附加到URL,如下所示:
http://localhost:8080/ch09/hello 2 . JSP;jsessionid = a09f3a 5583825 ee 787580106 cc 62a 1 E8
e:URL重寫本質上就是在URL連接中添加參數,將sessionID作為壹個值包含在連接中,這樣應用服務器就可以根據session ID從緩存中檢索會話。
TOMCAT服務器
會話跟蹤通常通過cookies和url重寫來實現。如果瀏覽器不禁止cookie,tomcat將首先使用cookie,否則將使用URL重寫來支持會話。
URL重寫的多余數據是服務器自動添加的,那麽服務器是怎麽添加的呢?當Tomcat返回響應時,檢查JSP頁面中的所有URL,包括所有鏈接和表單的Action屬性,並添加“;jsessionid=xxxxxx .添加url後綴的代碼片段如下:
org . Apache . coyote . Tomcat 5 . coyote response類的toEncoded()方法支持URL重寫。
1 string buffer sb = new string buffer(path);
2 if(sb . length()>;0 ) { // jsessionid不能是第壹個。
3 sb .追加(";jsessionid = ");
4 sb . append(session id);
5 }
6 sb.append(主播);
7 sb.append(查詢);
8 return(sb . tostring());