session生命周期


session生命周期

原文鏈接:http://blog.sina.com.cn/s/blog_72c8c1150100qpgl.html

文中黃色字體為我的標記修改或添加

Session保存在服務器端。為了獲得更高的存取速度,服務器一般把Session放在內存里。每個用戶都會有一個獨立的Session。如果Session內容過於復雜,當大量客戶訪問服務器時可能會導致內存溢出。因此,Session里的信息應該盡量精簡。

Session在用戶第一次訪問服務器的時候自動創建。需要注意只有訪問JSP、Servlet等程序時才會創建Session,只訪問HTML、IMAGE等靜態資源並不會創建Session。如果尚未生成Session,也可以使用request.getSession(true)強制生成Session。

Session生成后,只要用戶繼續訪問,服務器就會更新Session的最后訪問時間,並維護該Session。用戶每訪問服務器一次,無論是否讀寫Session,服務器都認為該用戶的Session"活躍(active)"了一次。

由於會有越來越多的用戶訪問服務器,因此Session也會越來越多。為防止內存溢出,服務器會把長時間內沒有活躍的Session從內存刪除。這個時間就是Session的超時時間。如果超過了超時時間沒訪問過服務器,Session就自動失效了。

Session的超時時間為maxInactiveInterval屬性,可以通過對應的getMaxInactiveInterval()獲取,通過setMaxInactiveInterval(long interval)修改。

筆記:設置session生命周期的三種方法;
方式一:
在Servlet中設置
HttpSession session = request.getSession();
session.setMaxInactiveInterval(60);//單位為秒
方式二:
在web.xml中設置session-config如下:
<session-config>
<session-timeout>2(單位:分鍾)</session-timeout>
</session-config>
方式三:
在Tomcat的/conf/web.xml中session-config,默認值為:30分鍾 配置全局Session生命周期,即所有在該服務器中部署的項目都會使用
<session-config>
<session-timeout>30</session-timeout>
</session-config>
優先級:Servlet中API設置 > 程序/web.xml設置 > Tomcat/conf/web.xml設置

Session的超時時間也可以在web.xml中修改。另外,通過調用Session的invalidate()方法可以使Session失效。

筆記: 使session失效的方法: session.invalidate() ;
Session中包括各種方法,使用起來要比Cookie方便得多。Session的常用方法如下。

 HttpSession的常用方法:

void setAttribute(String attribute, Object value) 設置Session屬性。value參數可以為任何Java Object。通常為Java Bean。value信息不宜過大

String getAttribute(String attribute) 返回Session屬性

Enumeration getAttributeNames() 返回Session中存在的屬性名

void removeAttribute(String attribute) 移除Session屬性

String getId() 返回Session的ID。該ID由服務器自動創建,不會重復

long getCreationTime() 返回Session的創建日期。返回類型為long,常被轉化為Date類型,例如:Date createTime = new Date(session.getCreationTime())

long getLastAccessedTime() 返回Session的最后活躍時間。返回類型為long
int getMaxInactiveInterval() 返回Session的超時時間。單位為秒。超過該時間沒有訪問,服務器認為該Session失效
void setMaxInactiveInterval(int second) 設置Session的超時時間。單位為秒
void putValue(String attribute, Object value)
  不推薦的方法。已經被setAttribute(String attribute, Object Value)替代
Object getValue(String attribute) 不被推薦的方法。已經被getAttribute(String attr)替代
boolean isNew() 返回該Session是否是新創建的
void invalidate() 使該Session失效

Session對瀏覽器的要求

雖然Session保存在服務器,對客戶端是透明的,它的正常運行仍然需要客戶端瀏覽器的支持。這是因為Session需要使用Cookie作為識別標志。HTTP協議是無狀態的,Session不能依據HTTP連接來判斷是否為同一客戶,因此服務器向客戶端瀏覽器發送一個名為JSESSIONID的Cookie,它的值為該Session的id(也就是HttpSession.getId()的返回值)。(筆記:JESSIONID = HttpSession.getId())Session依據該Cookie來識別是否為同一用戶。

該Cookie為服務器自動生成的,它的maxAge屬性一般為-1,表示僅當前瀏覽器內有效,並且各瀏覽器窗口間不共享,關閉瀏覽器就會失效。(默認值是-1,表示關閉瀏覽器,cookie就會消失。如果是正數,表示從現在開始,即將過期的seconds。)因此同一機器的兩個瀏覽器窗口訪問服務器時,會生成兩個不同的Session。但是由瀏覽器窗口內的鏈接、腳本等打開的新窗口(也就是說不是雙擊桌面瀏覽器圖標等打開的窗口)除外。這類子窗口會共享父窗口的Cookie,因此會共享一個Session。

注意:新開的瀏覽器窗口會生成新的Session,但子窗口除外。子窗口會共用父窗口的Session。例如,在鏈接上右擊,在彈出的快捷菜單中選擇"在新窗口中打開"時,子窗口便可以訪問父窗口的Session。

如果客戶端瀏覽器將Cookie功能禁用,或者不支持Cookie怎么辦?例如,絕大多數的手機瀏覽器都不支持Cookie。Java Web提供了另一種解決方案:URL地址重寫。

URL地址重寫

URL地址重寫是對客戶端不支持Cookie的解決方案。URL地址重寫的原理是將該用戶Session的id信息重寫到URL地址中。服務器能夠解析重寫后的URL獲取Session的id。這樣即使客戶端不支持Cookie,也可以使用Session來記錄用戶狀態。HttpServletResponse類提供了encodeURL(String url)實現URL地址重寫,例如:

<a href="<%= response.encodeURL("index.jsp?c=1&wd=Java") %>">Homepage</a>該方法會自動判斷客戶端是否支持Cookie。如果客戶端支持Cookie,會將URL原封不動地輸出來。如果客戶端不支持Cookie,則會將用戶Session的id重寫到URL中。重寫后的輸出可能是這樣的:

<td><a href="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=1&wd=Java">Homepage</a> 即在文件名的后面,在URL參數的前面添加了字符串";jsessionid=XXX"。其中XXX為Session的id。分析一下可以知道,增添的jsessionid字符串既不會影響請求的文件名,也不會影響提交的地址欄參數。用戶單擊這個鏈接的時候會把Session的id通過URL提交到服務器上,服務器通過解析URL地址獲得Session的id。

如果是頁面重定向(Redirection),URL地址重寫可以這樣寫:

<% if("administrator".equals(userName)){response.sendRedirect(response.encodeRedirectURL("administrator.jsp"));  return;} %> 效果跟response.encodeURL(String url)是一樣的:如果客戶端支持Cookie,生成原URL地址,如果不支持Cookie,傳回重寫后的帶有jsessionid字符串的地址。

對於WAP程序,由於大部分的手機瀏覽器都不支持Cookie,WAP程序都會采用URL地址重寫來跟蹤用戶會話。比如用友集團的移動商街等。

注意:TOMCAT判斷客戶端瀏覽器是否支持Cookie的依據是請求中是否含有Cookie。盡管客戶端可能會支持Cookie,但是由於第一次請求時不會攜帶任何Cookie(因為並無任何Cookie可以攜帶),URL地址重寫后的地址中仍然會帶有jsessionid。當第二次訪問時服務器已經在瀏覽器中寫入Cookie了,因此URL地址重寫后的地址中就不會帶有jsessionid了。

Session中禁止使用Cookie

既然WAP上大部分的客戶瀏覽器都不支持Cookie,索性禁止Session使用Cookie,統一使用URL地址重寫會更好一些。Java Web規范支持通過配置的方式禁用Cookie。下面舉例說一下怎樣通過配置禁止使用Cookie。

打開項目sessionWeb的WebRoot目錄下的META-INF文件夾(跟WEB-INF文件夾同級,如果沒有則創建),打開context.xml(如果沒有則創建),編輯內容如下:

/META-INF/context.xml

<?xml version='1.0' encoding='UTF-8'?> <Context path="/sessionWeb" cookies="false"> </Context> 或者修改Tomcat全局的conf/context.xml,修改內容如下:

context.xml

<!-- The contents of this file will be loadedfor each web application --> <Context cookies="false">      <!-- ... 中間代碼略 --> </Context> 部署后TOMCAT便不會自動生成名JSESSIONID的Cookie,Session也不會以Cookie為識別標志,而僅僅以重寫后的URL地址為識別標志了。

注意:該配置只是禁止Session使用Cookie作為識別標志,並不能阻止其他的Cookie讀寫。也就是說服務器不會自動維護名為JSESSIONID的Cookie了,但是程序中仍然可以讀寫其他的Cookie。

Session與Cookie的比較

Cookie與Session都可以進行會話跟蹤,但是實現的原理不太一樣。一般情況下二者均可以滿足需求,但有時候不可以使用Cookie,有時候不可以使用Session。下面通過比較說明二者的特點以及適用的場合。

5.3.1 從存取方式上比較

Cookie中只能保存ASCII字符串,如果需要存取Unicode字符或者二進制數據,需要進行UTF-8,GBK或者BASE64等方式的編碼。Cookie中也不能直接存取Java對象。若要存儲稍微復雜的信息,使用Cookie是比較困難的。

而Session中可以存取任何類型的數據,包括而不限於String、Integer、List、Map等。Session中也可以直接保存Java Bean乃至任何Java類,對象等,使用起來非常方便。可以把Session看做是一個Java容器類。

從隱私安全上比較

Cookie存儲在客戶端瀏覽器中,對客戶端是可見的,客戶端的一些程序可能會窺探、復制甚至修改Cookie中的內容。而Session存儲在服務器上,對客戶端是透明的,不存在敏感信息泄露的危險。

如果選用Cookie,比較好的辦法是,敏感的信息如賬號密碼等盡量不要寫到Cookie中。最好是像Google、Baidu那樣將Cookie信息加密,提交到服務器后再進行解密,保證Cookie中的信息只有自己能讀得懂。而如果選擇Session就省事多了,反正是放在服務器上,Session里任何隱私都可以。


從有效期上比較

使用過Google的人都知道,如果登錄過Google,則Google的登錄消息長期有效。用戶不必每次訪問都重新登錄,Google會長久地記錄該用戶的登錄信息。要達到這種效果,使用Cookie會是比較好的選擇。只需要設置Cookie的maxAge屬性為一個很大很大的數字或者Integer.MAX_VALUE就可以了。Cookie的maxAge屬性支持這樣的效果。

使用Session理論上也能實現這種效果。只要調用方法setMaxInactiveInterval(Integer. MAX_VALUE)不就可以了么。但是由於Session依賴於名為JSESSIONID的Cookie,而Cookie JSESSIONID的maxAge默認為-1,只要關閉了瀏覽器該Session就會失效,因此Session不能實現信息永久有效的效果。使用URL地址重寫也不能實現。

而且如果設置Session的超時時間過長,服務器累計的Session就會越多,越容易導致內存溢出。

筆記:為什么不能使用session實現登陸信息長時間有效:

1. session需要依賴jsessionid,而jsessionid的maxAge為-1,也就是當關閉瀏覽器后存在cookie中的jsessionid就會丟失,當該客戶端再次請求服務器時,即使該客戶端上次會話對應的session對象仍然存在於服務器內存中(因為設置了maxInactiveInterval很大),但是該客戶端的第二次請求沒有jsessionid,所以服務器無法根據jsessionid找到上次訪問時的session對象。

2. 如果設置session超時時間過長,服務器累計session就會越多,越容易導致內存溢出。


從對服務器的負擔上比較

Session是保存在服務器端的,每個用戶都會產生一個Session。如果並發訪問的用戶非常多,會產生非常多的Session,消耗大量的內存。因此像Google、Baidu、Sina這樣並發訪問量極高的網站,是不太可能使用Session來追蹤客戶會話的。

而Cookie保存在客戶端,不占用服務器資源。如果並發瀏覽的用戶非常多,Cookie是很好的選擇。對於Google、Baidu、Sina來說,Cookie也許是唯一的選擇。

從瀏覽器支持上比較

Cookie是需要客戶端瀏覽器支持的。如果客戶端禁用了Cookie,或者不支持Cookie,則會話跟蹤會失效。對於WAP上的應用,常規的Cookie就派不上用場了。

如果客戶端瀏覽器不支持Cookie,需要使用Session以及URL地址重寫。需要注意的是所有的用到Session程序的URL都要使用response.encodeURL(String URL)或者response.encodeRedirectURL(String URL)進行URL地址重寫,否則導致Session會話跟蹤失敗。對於WAP應用來說,Session+URL地址重寫也許是它唯一的選擇。

如果客戶端支持Cookie,則Cookie既可以設為僅本瀏覽器窗口(當前打開的這個瀏覽器窗口選項卡)以及其子窗口內有效(把maxAge設為-1),也可以設為所有瀏覽器窗口( 同一進程多個瀏覽器選項卡或者多個進程)內有效(把maxAge設為某個大於0的整數)。但Session只能在本瀏覽器窗口以及其子窗口內有效。如果兩個瀏覽器窗口互不相干,它們將使用兩個不同的Session。session是服務器端對象與瀏覽器沒有關系,如果客戶端瀏覽器存有表示當前session的cookie中的jsessionid,那么就可以訪問到session,如果沒有就訪問不到session。


從跨域名上比較

Cookie支持跨域名訪問,例如將domain屬性設置為".helloweenvsfei.com",則以".helloweenvsfei.com"為后綴的所有域名均可以訪問該Cookie。跨域名Cookie現在被廣泛用在網絡中,例如Google、Baidu、Sina等。而Session則不會支持跨域名訪問。Session僅在他所在的域名內有效。

注意:僅使用Cookie或者僅使用Session可能實現不了理想的效果。這時應該嘗試一下同時使用Cookie與Session。Cookie與Session的搭配使用在實際項目中會實現絢爛多姿的效果。


本章小結

Cookie是早期的會話跟蹤技術,它將信息保存到客戶端瀏覽器中。瀏覽器訪問網站時會攜帶這些Cookie信息,達到鑒別身份的目的。

Session是在Cookie基礎上建立的會話跟蹤技術,它將信息保存在服務器端,Session中能夠存儲負責的Java對象,因此使用更加方便。Session依賴於名為JSESSIONID的Cookie。

如果客戶端瀏覽器不支持Cookie,或者禁用了Cookie,仍然可以通過使用URL地址重寫來使用Session。

 
 
 
 


免責聲明!

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



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