1、cookie機制和session機制的區別
***********************************************************************
具體來講cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在服務器端保持狀態的方案。
同時咱們也看到,因爲才服務器端保持狀態的方案在客戶端也須要保存一個標識,因此session
機制可能須要藉助於cookie機制來達到保存標識的目的,但實際上還有其餘選擇
***********************************************************************javascript
2、會話cookie和持久cookie的區別
***********************************************************************
若是不設置過時時間,則表示這個cookie生命週期爲瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。這種生命期爲瀏覽會話期的cookie被稱爲會話cookie。會話cookie通常不保存在硬盤上而是保存在內存裏。
若是設置了過時時間,瀏覽器就會把cookie保存到硬盤上,關閉後再次打開瀏覽器,這些cookie依然有效直到超過設定的過時時間。
存儲在硬盤上的cookie能夠在不一樣的瀏覽器進程間共享,好比兩個IE窗口。而對於保存在內存的cookie,不一樣的瀏覽器有不一樣的處理方式。
***********************************************************************php
3、如何利用實現自動登陸
***********************************************************************
當用戶在某個網站註冊後,就會收到一個唯一用戶ID的cookie。客戶後來從新鏈接時,這個
用戶ID會自動返回,服務器對它進行檢查,肯定它是否爲註冊用戶且選擇了自動登陸,從而使用戶務需給出明確的用戶名和密碼,就能夠訪問服務器上的資源。
************************************************************************html
4、如何根據用戶的愛好定製站點
************************************************************************
網站可使用cookie記錄用戶的意願。對於簡單的設置,網站能夠直接將頁面的設置存儲在cookie中完成定製。然而對於更復雜的定製,網站只需僅將一個唯一的標識符發送給用戶,由服務器端的數據庫存儲每一個標識符對應的頁面設置。
************************************************************************java
5、cookie的發送
************************************************************************
1.建立Cookie對象
2.設置最大時效
3.將Cookie放入到HTTP響應報頭
若是你建立了一個cookie,並將他發送到瀏覽器,默認狀況下它是一個會話級別的cookie:存儲在瀏覽器的內存中,用戶退出瀏覽器以後被刪除。若是你但願瀏覽器將該cookie存儲在磁盤上,則
須要使用maxAge,並給出一個以秒爲單位的時間。將最大時效設爲0則是命令瀏覽器刪除該cookie。
發送cookie須要使用HttpServletResponse的addCookie方法,將cookie插入到一個Set-Cookie HTTP請 求報頭中。因爲這個方法並不修改任何以前指定的Set-Cookie報頭,而是建立新的報頭,所以咱們將這個方法稱爲是addCookie,而非 setCookie。一樣要記住響應報頭必須在任何文檔內容發送到客戶端以前設置。web
6、cookie的讀取
*************************************************************************
1.調用request.getCookie
要獲取有瀏覽器發送來的cookie,須要調用HttpServletRequest的getCookies方法,這個調用返回Cookie對象的數組,對應由HTTP請求中Cookie報頭輸入的值。
2.對數組進行循環,調用每一個cookie的getName方法,直到找到感興趣的cookie爲止
cookie與你的主機(域)相關,而非你的servlet或JSP頁面。於是,儘管你的servlet可能只發送了單個cookie,你也可能會獲得許多不相關的cookie。
例如:
String cookieName = 「userID」;
Cookie cookies[] = request.getCookies();
if (cookies!=null){
for(int i=0;i<cookies.length;i++){
Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName())){
doSomethingWith(cookie.getValue());
}
}
}
************************************************************************數據庫
7、如何使用cookie檢測初訪者
************************************************************************
A.調用HttpServletRequest.getCookies()獲取Cookie數組
B.在循環中檢索指定名字的cookie是否存在以及對應的值是否正確
C.若是是則退出循環並設置區別標識
D.根據區別標識判斷用戶是否爲初訪者從而進行不一樣的操做
************************************************************************apache
8、使用cookie檢測初訪者的常見錯誤
************************************************************************
不能僅僅由於cookie數組中不存在在特定的數據項就認爲用戶是個初訪者。若是cookie數組爲null,客戶多是一個初訪者,也多是因爲用戶將cookie刪除或禁用形成的結果。
可是,若是數組非null,也不過是顯示客戶曾經到過你的網站或域,並不能說明他們曾經訪問過你的servlet。其它servlet、JSP頁面以及非Java Web應用均可以設置cookie,依據路徑的設置,其中的任何cookie都有可能返回給用戶的瀏覽器。
正確的作法是判斷cookie數組是否爲空且是否存在指定的Cookie對象且值正確。
************************************************************************數組
9、使用cookie屬性的注意問題
************************************************************************
屬性是從服務器發送到瀏覽器的報頭的一部分;但它們不屬於由瀏覽器返回給服務器的報頭。
所以除了名稱和值以外,cookie屬性只適用於從服務器輸出到客戶端的cookie;服務器端來自於瀏覽器的cookie並無設置這些屬性。
於是不要指望經過request.getCookies獲得的cookie中可使用這個屬性。這意味着,你不能僅僅經過設置cookie的最大時 效,發出它,在隨後的輸入數組中查找適當的cookie,讀取它的值,修改它並將它存回Cookie,從而實現不斷改變的cookie值。
************************************************************************瀏覽器
10、如何使用cookie記錄各個用戶的訪問計數
************************************************************************
1.獲取cookie數組中專門用於統計用戶訪問次數的cookie的值
2.將值轉換成int型
3.將值加1並用原來的名稱從新建立一個Cookie對象
4.從新設置最大時效
5.將新的cookie輸出
************************************************************************安全
11、session在不一樣環境下的不一樣含義
************************************************************************
session,中文常常翻譯爲會話,其原本的含義是指善始善終的一系列動做/消息,好比打電話是從拿起電話撥號到掛斷電話這中間的一系列過程能夠稱之爲一個session。
然而當session一詞與網絡協議相關聯時,它又每每隱含了「面向鏈接」和/或「保持狀態」這樣兩個含義。
session在Web開發環境下的語義又有了新的擴展,它的含義是指一類用來在客戶端與服務器端之間保持狀態的解決方案。有時候Session也用來指這種解決方案的存儲結構。
************************************************************************
12、session的機制
************************************************************************
session機制是一種服務器端的機制,服務器使用一種相似於散列表的結構(也可能就是使用散列表)來保存信息。
但程序須要爲某個客戶端的請求建立一個session的時候,服務器首先檢查這個客戶端的請求裏是否包含了一個session標識-稱爲session id,若是已經包含一個session id則說明之前已經爲此客戶建立過session,服務器就按照session id把這個session檢索出來使用(若是檢索不到,可能會新建一個,這種狀況可能出如今服務端已經刪除了該用戶對應的session對象,但用戶人爲 地在請求的URL後面附加上一個JSESSION的參數)。
若是客戶請求不包含session id,則爲此客戶建立一個session而且生成一個與此session相關聯的session id,這個session id將在本次響應中返回給客戶端保存。
************************************************************************
十3、保存session id的幾種方式
************************************************************************
A.保存session id的方式能夠採用cookie,這樣在交互過程當中瀏覽器能夠自動的按照規則把這個標識發送給服務器。
B.因爲cookie能夠被人爲的禁止,必須有其它的機制以便在cookie被禁止時仍然可以把session id傳遞迴服務器,常常採用的一種技術叫作URL重寫,就是把session id附加在URL路徑的後面,附加的方式也有兩種,一種是做爲URL路徑的附加信息,另外一種是做爲查詢字符串附加在URL後面。網絡在整個交互過程當中始終 保持狀態,就必須在每一個客戶端可能請求的路徑後面都包含這個session id。
C.另外一種技術叫作表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。
************************************************************************
十4、session何時被建立
************************************************************************
一個常見的錯誤是覺得session在有客戶端訪問時就被建立,然而事實是直到某server端程序(如Servlet)調用HttpServletRequest.getSession(true)這樣的語句時纔會被建立。
************************************************************************
十5、session什麼時候被刪除
************************************************************************
session在下列狀況下被刪除:
A.程序調用HttpSession.invalidate()
B.距離上一次收到客戶端發送的session id時間間隔超過了session的最大有效時間
C.服務器進程被中止
再次注意關閉瀏覽器只會使存儲在客戶端瀏覽器內存中的session cookie失效,不會使服務器端的session對象失效。
************************************************************************
十6、URL重寫有什麼缺點
************************************************************************
對全部的URL使用URL重寫,包括超連接,form的action,和重定向的URL。每一個引用你的站點的URL,以及那些返回給用戶的URL(即便經過間接手段,好比服務器重定向中的Location字段)都要添加額外的信息。
這意味着在你的站點上不能有任何靜態的HTML頁面(至少靜態頁面中不能有任何連接到站點動態頁面的連接)。所以,每一個頁面都必須使用 servlet或JSP動態生成。即便全部的頁面都動態生成,若是用戶離開了會話並經過書籤或連接再次回來,會話的信息都會丟失,由於存儲下來的連接含有 錯誤的標識信息-該URL後面的SESSION ID已通過期了。
************************************************************************
十7、使用隱藏的表單域有什麼缺點
************************************************************************
僅當每一個頁面都是有表單提交而動態生成時,才能使用這種方法。單擊常規的<A HREF..>超文本連接並不產生表單提交,所以隱藏的表單域不能支持一般的會話跟蹤,只能用於一系列特定的操做中,好比在線商店的結帳過程
************************************************************************
十8、會話跟蹤的基本步驟
************************************************************************
1.訪問與當前請求相關的會話對象
2.查找與會話相關的信息
3.存儲會話信息
4.廢棄會話數據
************************************************************************
十9、getSession()/getSession(true)、getSession(false)的區別
************************************************************************
getSession()/getSession(true):當session存在時返回該session,不然新建一個session並返回該對象
getSession(false):當session存在時返回該session,不然不會新建session,返回null
************************************************************************
二10、如何將信息於會話關聯起來
************************************************************************
setAttribute會替換任何以前設定的值;若是想要在不提供任何代替的狀況下移除某個值,則應使用removeAttribute。這個方法會觸發全部實現了HttpSessionBindingListener接口的值的valueUnbound
方法。
************************************************************************
二11、會話屬性的類型有什麼限制嗎
************************************************************************
一般會話屬性的類型只要是Object就能夠了。除了null或基本類型,如int,double,boolean。
若是要使用基本類型的值做爲屬性,必須將其轉換爲相應的封裝類對象
************************************************************************
二12、如何廢棄會話數據
************************************************************************
A.只移除本身編寫的servlet建立的數據:
調用removeAttribute(「key」)將指定鍵關聯的值廢棄
B.刪除整個會話(在當前Web應用中):
調用invalidate,將整個會話廢棄掉。這樣作會丟失該用戶的全部會話數據,而非僅僅由咱們
servlet或JSP頁面建立的會話數據
C.將用戶從系統中註銷並刪除全部屬於他(或她)的會話
調用logOut,將客戶從Web服務器中註銷,同時廢棄全部與該用戶相關聯的會話(每一個Web應用至多一個)。這個操做有可能影響到服務器上多個不一樣的Web應用
************************************************************************
二十3、使用isNew來判斷用戶是否爲新舊用戶的錯誤作法
************************************************************************
public boolean isNew()方法若是會話還沒有和客戶程序(瀏覽器)發生任何聯繫,則這個方法返回true,這通常是由於會話是新建的,不是由輸入的客戶請求所引發的。
但若是isNew返回false,只不過是說明他以前曾經訪問該Web應用,並不表明他們曾訪問過咱們的servlet或JSP頁面。
由於session是與用戶相關的,在用戶以前訪問的每個頁面都有可能建立了會話。所以isNew爲false只能說用戶以前訪問過該Web應用,session能夠是當前頁面建立,也多是由用戶以前訪問過的頁面建立的。
正確的作法是判斷某個session中是否存在某個特定的key且其value是否正確
************************************************************************
二十4、Cookie的過時和Session的超時有什麼區別
************************************************************************
會話的超時由服務器來維護,它不一樣於Cookie的失效日期。首先,會話通常基於駐留內存的cookie
不是持續性的cookie,於是也就沒有截至日期。即便截取到JSESSIONID cookie,併爲它設定一個失效日期發送出去。瀏覽器會話和服務器會話也會大相徑庭。
************************************************************************
二十5、session cookie和session對象的生命週期是同樣的嗎
************************************************************************
當用戶關閉了瀏覽器雖然session cookie已經消失,但session對象仍然保存在服務器端
************************************************************************
二十6、是否只要關閉瀏覽器,session就消失了
************************************************************************
程序通常都是在用戶作log off的時候發個指令去刪除session,然而瀏覽器歷來不會主動在關閉以前通知服務器它將要被關閉,所以服務器根本不會有機會知道瀏覽器已經關閉。服務器會一直保留這個會話對象直到它處於非活動狀態超過設定的間隔爲止。
之因此會有這種錯誤的認識,是由於大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個session id就消失了,再次鏈接到服務器時也就沒法找到原來的session。
若是服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求報頭,把原來的session id發送到服務器,則再次打開瀏覽器仍然可以找到原來的session。
偏偏是因爲關閉瀏覽器不會致使session被刪除,迫使服務器爲session設置了一個失效時間,當距離客戶上一次使用session的時間超過了這個失效時間時,服務器就能夠認爲客戶端已經中止了活動,纔會把session刪除以節省存儲空間。
由此咱們能夠得出以下結論:
關閉瀏覽器,只會是瀏覽器端內存裏的session cookie消失,但不會使保存在服務器端的session對象消失,一樣也不會使已經保存到硬盤上的持久化cookie消失。
************************************************************************
二十7、打開兩個瀏覽器窗口訪問應用程序會使用同一個session仍是不一樣的session
************************************************************************
一般session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的session id,這樣咱們信息共享的目的就達不到了。
此時咱們能夠先把session id保存在persistent cookie中(經過設置session的最大有效時間),而後在新窗口中讀出來,就能夠獲得上一個窗口的session id了,這樣經過session cookie和persistent cookie的結合咱們就能夠實現了跨窗口的會話跟蹤。
************************************************************************
二十8、如何使用會話顯示每一個客戶的訪問次數
************************************************************************
因爲客戶的訪問次數是一個整型的變量,但session的屬性類型中不能使用int,double,boolean等基本類型的變量,因此咱們要用到這些基本類型的封裝類型對象做爲session對象中屬性的值
但像Integer是一種不可修改(Immutable)的數據結構:構建後就不能更改。這意味着每一個請求都必須建立新的Integer對象,以後使用setAttribute來代替以前存在的老的屬性的值。例如:
HttpSession session = request.getSession();
SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(「SomeIdentifier」);
if (value= =null){
value = new SomeImmutableClass(…); // 新建立一個不可更改對象
}else{
value = new SomeImmutableClass(calculatedFrom(value)); // 對value從新計算後建立新的對象
}
session.setAttribute(「someIdentifier」,value); // 使用新建立的對象覆蓋原來的老的對象
************************************************************************
二十9、如何使用會話累計用戶的數據
************************************************************************
使用可變的數據結構,好比數組、List、Map或含有可寫字段的應用程序專有的數據結構。經過這種方式,除非首次分配對象,不然不須要調用setAttribute。例如
HttpSession session = request.getSession();
SomeMutableClass value = (SomeMutableClass)session.getAttribute(「someIdentifier」);
if(value = = null){
value = new SomeMutableClass(…);
session.setAttribute(「someIdentifier」,value);
}else{
value.updateInternalAttribute(…); // 若是已經存在該對象則更新其屬性而不需從新設置屬性
}
************************************************************************
三10、不可更改對象和可更改對象在會話數據更新時的不一樣處理
************************************************************************
不可更改對象由於一旦建立以後就不能更改,因此每次要修改會話中屬性的值的時候,都須要
調用setAttribute(「someIdentifier」,newValue)來代替原有的屬性的值,不然屬性的值不會被更新
可更改對象由於其自身通常提供了修改自身屬性的方法,因此每次要修改會話中屬性的值的時
候,只要調用該可更改對象的相關修改自身屬性的方法就能夠了。這意味着咱們就不須要調
用setAttribute方法了
************************************************************************
2.cookies的屬性有:Domain(域):哪一個站點發的哪一個站點拿走
Expires:是否過時
Haskeys:是否包含關鍵
path:存放的路徑
secure:是否安全
注:---cookies的設置在 sever端設置,路徑與域一塊兒構成cookie的做用範圍?
這個是什麼意思的啊?爲何會是在服務器端進行設置的呢?
若不設置過時時間,則表示這個cookie的生命期爲瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失。這種生命期爲瀏覽器會話期的cookie被稱 爲會話cookie。會話cookie通常不存儲在硬盤上而是保存在內存裏,固然這種行爲並非規範規定的。若設置了過時時間,瀏覽器就會把cookie 保存到硬盤上,關閉後再次打開瀏覽器,這些cookie仍然有效直到超過設定的過時時間。存儲在硬盤上的cookie能夠在不一樣的瀏覽器進程間共享,好比 兩個IE窗口。而對於保存在內存裏的cookie,不一樣的瀏覽器有不一樣的處理方式
IE與FF的區別哦!FF是共享的而IE當打開不一樣的窗口的時候是不共享 的
3.session(會話):適用於同一客戶在一個站點,不一樣頁面上的瀏覽;適用於同一客戶在一個頁面上,不斷的刷新。
6.當程序須要爲某個客戶端的請求建立一個session時,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識(稱爲session id),若是已包含則說明之前已經爲此客戶端建立過session,服務器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),若是客戶端請求不包含session id,則爲此客戶端建立一個session而且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。
IE中:
有效的窗中包括
1.Session對象只在創建Session對象的窗口中有效。
2.在創建Session對象的窗口中新開連接的窗口
無效的窗口包括
1.直接啓動IE瀏覽器的窗口
2.不是在創建Session對象的窗口中新開連接的窗口
***********************************************************************
cookie的內容主要包括:名字,值,過時時間,路徑和域。
其中,
域能夠指定某一個域好比.google.com,至關於總店招牌,好比寶潔公司,也能夠指定一個域下的具體某臺機器好比www.google.com或者froogle.google.com,能夠用飄柔來作比。
路徑就是跟在域名後面的URL路徑,好比/或者/foo等等,能夠用某飄柔專櫃作比。
路徑與域合在一塊兒就構成了cookie的做用範圍。
若是不設置過時時間,則表示這個cookie的生命期爲瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。這種生命期爲瀏覽器會話期的 cookie被稱爲會話cookie。會話cookie通常不存儲在硬盤上而是保存在內存裏,固然這種行爲並非規範規定的。若是設置了過時時間,瀏覽器 就會把cookie保存到硬盤上,關閉後再次打開瀏覽器,這些cookie仍然有效直到超過設定的過時時間。
存儲在硬盤上的cookie能夠在不一樣的瀏覽器進程間共享,好比兩個IE窗口。而對於保存在內存裏的cookie,不一樣的瀏覽器有不一樣的處理方式。對於 IE,在一個打開的窗口上按Ctrl-N(或者從文件菜單)打開的窗口能夠與原窗口共享,而使用其餘方式新開的IE進程則不能共享已經打開的窗口的內存 cookie;對於Mozilla Firefox0.8,全部的進程和標籤頁均可以共享一樣的cookie。通常來講是用javascript的window.open打開的窗口會與原窗 口共享內存cookie。瀏覽器對於會話cookie的這種只認cookie不認人的處理方式常常給採用session機制的web應用程序開發者形成很 大的困擾。
[經典的語錄]
下面就是一個goolge設置cookie的響應頭的例子
HTTP/1.1 302 Found
Location: http://www.google.com/intl/zh-CN/
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Content-Type: text/html
到時候咱們的域就要設置爲domain=.*****.cn path=/
session機制是一種服務器端的機制,服務器使用一種相似於散列表的結構(也可能就是使用散列表)來保存信息。
4、理解session機制
session機制是一種服務器端的機制,服務器使用一種相似於散列表的結構(也可能就是使用散列表)來保存信息。
當程序須要爲某個客戶端的請求建立一個session的時候,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識 - 稱爲session id,若是已包含一個session id則說明之前已經爲此客戶端建立過session,服務器就按照session id把這個session檢索出來使用(若是檢索不到,可能會新建一個),若是客戶端請求不包含session id,則爲此客戶端建立一個session而且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。
保存這個session id的方式能夠採用cookie,這樣在交互過程當中瀏覽器能夠自動的按照規則把這個標識發揮給服務器。通常這個cookie的名字都是相似於 SEEESIONID,而。好比weblogic對於web應用程序生成的 cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!- 145788764,它的名字就是JSESSIONID。
因爲cookie能夠被人爲的禁止,必須有其餘機制以便在cookie被禁止時仍然可以把session id傳遞迴服務器。常常被使用的一種技術叫作URL重寫,就是把session id直接附加在URL路徑的後面,附加方式也有兩種,一種是做爲URL路徑的附加信息,表現形式爲http://..... /xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另外一種是做爲查詢字符串附加在URL後面,表現形式爲http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
這兩種方式對於用戶來講是沒有區別的,只是服務器在解析的時候處理的方式不一樣,採用第一種方式也有利於把session id的信息和正常程序參數區分開來。
爲了在整個交互過程當中始終保持狀態,就必須在每一個客戶端可能請求的路徑後面都包含這個session id。
另外一種技術叫作表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。好比下面的表單
<form name="testform" action="/xxx">
<input type="text">
</form>
在被傳遞給客戶端以前將被改寫成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
這種技術如今已較少應用,筆者接觸過的很古老的iPlanet6(SunONE應用服務器的前身)就使用了這種技術。
實際上這種技術能夠簡單的用對action應用URL重寫來代替。
在談論session機制的時候,經常聽到這樣一種誤解「只要關閉瀏覽器,session就消失了」。其實能夠想象一下會員卡的例子,除非顧客主動 對店家提出銷卡,不然店家絕對不會輕易刪除顧客的資料。對session來講也是同樣的,除非程序通知服務器刪除一個session,不然服務器會一直保 留,程序通常都是在用戶作log off的時候發個指令去刪除session。然而瀏覽器歷來不會主動在關閉以前通知服務器它將要關閉,所以服務器根本不會有機會知道瀏覽器已經關閉,之所 以會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個session id就消失了,再次鏈接服務器時也就沒法找到原來的session。若是服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的 HTTP請求頭,把原來的session id發送給服務器,則再次打開瀏覽器仍然可以找到原來的session。
偏偏是因爲關閉瀏覽器不會致使session被刪除,迫使服務器爲seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就能夠認爲客戶端已經中止了活動,纔會把session刪除以節省存儲空間。
[寫得太精彩了。感覺太深了!]
一、session在什麼時候被建立
一個常見的誤解是覺得session在有客戶端訪問時就被建立,然而事實是直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被建立,注意若是JSP沒有顯示的使用 <%@page session="false"%> 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的session對象的來歷。
因爲session會消耗內存資源,所以,若是不打算使用session,應該在全部的JSP中關閉它。
二、session什麼時候被刪除
綜合前面的討論,session在下列狀況下被刪除a.程序調用HttpSession.invalidate();或b.距離上一次收到客戶端發送的session id時間間隔超過了session的超時設置;或c.服務器進程被中止(非持久session)
三、如何作到在瀏覽器關閉時刪除session
嚴格的講,作不到這一點。能夠作一點努力的辦法是在全部的客戶端頁面裏使用javascript代碼window.oncolose來監視瀏覽器的關閉動做,而後向服務器發送一個請求來刪除session。可是對於瀏覽器崩潰或者強行殺死進程這些很是規手段仍然無能爲力。
七、開兩個瀏覽器窗口訪問應用程序會使用同一個session仍是不一樣的session
參見第三小節對cookie的討論,對session來講是隻認id不認人,所以不一樣的瀏覽器,不一樣的窗口打開方式以及不一樣的cookie存儲方式都會對這個問題的答案有影響。
八、如何防止用戶打開兩個瀏覽器窗口操做致使的session混亂
這個問題與防止表單屢次提交是相似的,能夠經過設置客戶端的令牌來解決。就是在服務器每次生成一個不一樣的id返回給客戶端,同時保存在session裏, 客戶端提交表單時必須把這個id也返回服務器,程序首先比較返回的id與保存在 session裏的值是否一致,若是不一致則說明本次操做已經被提交過了。[對不起你已經投過票了!能夠這樣來進行控制的哦]
8、總結
session機制自己並不複雜,然而其實現和配置上的靈活性卻使得具體狀況複雜多變。這也要求咱們不能把僅僅某一次的經驗或者某一個瀏覽器,服務器的經驗看成廣泛適用的經驗,而是始終須要具體狀況具體分析。
文章出處:DIY部落(http://www.diybl.com/course/3_program/java/javashl/20090306/158662.html)
************************************************************************
關於COOKIE和SESSION的關係,一直沒搞清楚。網上一搜COOKIE,廣泛都有會話COOKIE和持久COOKIE的概念。
rubyeye的博客裏有這樣的解釋,我把部分貼過來。(http://rubyeye.javaeye.com/blog/196117)
引用
當你第一次訪問一個網站的時候,網站服務器會在響應頭內加上
Set-Cookie:PHPSESSID=nj1tvkclp3jh83olcn3191sjq3(php服務器),或Set-Cookie JSESSIONID=nj1tvkclp3jh83olcn3191sjq3(java服務器)信息,此信息是服務器隨機生成的,放在服務器內存裏,爲 了標識惟一的客戶端用戶,內容不會重複,這就是sessionid.
當瀏覽器獲得這個sessionid會將它放在本身的進程內存裏,這裏不一樣的瀏覽器會有所不一樣,IE進程間不能共享這個sessionid,也就是新開一 個IE將不能共享這個sessionid;而Firefox進程間能夠共享.而後你繼續發請求給這個網站的時候,瀏覽器就會把這個sessionid放在 請求頭裏發送給該服務器了,這樣服務器獲得sessionid後再和本身內存裏存放的sessionid對比鎖定客戶端,從而區分不一樣客戶端,完成會話.
能夠看出若是用這種方式,當用戶在會話的過程當中關閉瀏覽器結束進程,則這個sessionid將消失,若是用戶又打開瀏覽器想繼續此次會話的時候,就會因 爲發送的請求中沒有這個sessionid而使服務器沒法辨別該把那個session信息給他,注意(這個時候服務器端的sessionid和 sessionid所指向的session都還存在,只是沒有正確的sessionid和它匹配而佔用服務器內存,只有session過時或服務器重啓才 釋放內存).
上面這種方式叫會話cookie,把cookie放在瀏覽器內存裏,只能在這個瀏覽器的內存範圍裏完成會話,是一種不長久的方式,爲了能長久會話,就出現 了持久化cookie,把cookie固化在用戶的計算機上,如今的cookie不僅僅能存放sessionid,還能放用戶信息,樣式表信息等.
若是用戶禁止了全部cookie的使用,那麼會話cookie和持久化cookie都不能用了,有個方案也能夠解決問題,就是URL重寫,這裏要說下的就是URL重寫只能實現會話cookie的效果,持久會話實現不了.
剛開始理解時,我也認爲會有持久和會話這兩種COOKIE。我認爲,
會話COOKIE就是用來存放SESSIONID的,而且只存在於瀏覽器內存,瀏覽器關閉後會話COOKIE就被刪除;
持久COOKIE就是用來存放其它信息,而且是在咱們的本地硬盤裏能看到的那種COOKIE。
而後我寫了個SERVLET試了一下。
Java代碼
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
Cookie cookie = null;
PrintWriter out = response.getWriter();
out.println("<html><body>");
Cookie[] cookies = request.getCookies();
// 若是沒有COOKIE,新建一個COOKIE
if (cookies == null) {
out.println("<b>cookies is null.</b></br>");
cookie = new Cookie("new", "1");
response.addCookie(cookie);
} else {
out.println("<b>cookies is not null.</b></br>");
for (int i = 0; i < cookies.length; i++) {
cookie = cookies[i];
out.println("cookie" + i + " name: " + cookie.getName() + "</br>");
}
}
HttpSession session = request.getSession();
if (session == null) {
out.println("<b>session is null.</b></br>");
} else {
out.println("<b>session is not null.</b></br>");
out.println("session id: " + session.getId() + "</br>");
}
out.println("</body></html>");
}
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
Cookie cookie = null;
PrintWriter out = response.getWriter();
out.println("<html><body>");
Cookie[] cookies = request.getCookies();
// 若是沒有COOKIE,新建一個COOKIE
if (cookies == null) {
out.println("<b>cookies is null.</b></br>");
cookie = new Cookie("new", "1");
response.addCookie(cookie);
} else {
out.println("<b>cookies is not null.</b></br>");
for (int i = 0; i < cookies.length; i++) {
cookie = cookies[i];
out.println("cookie" + i + " name: " + cookie.getName() + "</br>");
}
}
HttpSession session = request.getSession();
if (session == null) {
out.println("<b>session is null.</b></br>");
} else {
out.println("<b>session is not null.</b></br>");
out.println("session id: " + session.getId() + "</br>");
}
out.println("</body></html>");
}
第一次訪問這個SERVLET,頁面顯示
引用
cookies is null.
session is not null.
session id: 0D0AABB6F911362FEE87BEEB2953C33F
第二次訪問,頁面顯示
引用
cookies is not null.
cookie0 name: new
cookie1 name: JSESSIONID
session is not null.
session id: 0D0AABB6F911362FEE87BEEB2953C33F
第二次訪問時從客戶端來了兩個COOKIE,名爲「new」的COOKIE是我建立的,名爲「JSESSIONID」的COOKIE應該是服務器TOMCAT建立的,但這時,在本地硬盤裏找不到這兩個COOKIE的文件。
改一下SERVLET,在建立名爲「new」的COOKIE時,加一句
Java代碼
cookie.setMaxAge(1000);
cookie.setMaxAge(1000);
而後本地硬盤裏就有「new」這個COOKIE了。
這下就有疑問了,在沒有設置COOKIE存活期時,本身建立的SESSION不會存到本地硬盤,會不會TOMCAT建立的所謂的會話COOKIE也是沒有設置存活期呢?
而後根據zddava的博客(http://zddava.javaeye.com/blog/311053),找到了TOMCAT裏建立會話COOKIE的代碼。
在
org.apache.catalina.connector.Request.java裏,
Java代碼
protected void configureSessionCookie(Cookie cookie) {
cookie.setMaxAge(-1);
String contextPath = null;
if (!connector.getEmptySessionPath() && (getContext() != null)) {
contextPath = getContext().getEncodedPath();
}
if ((contextPath != null) && (contextPath.length() > 0)) {
cookie.setPath(contextPath);
} else {
cookie.setPath("/");
}
if (isSecure()) {
cookie.setSecure(true);
}
}
protected void configureSessionCookie(Cookie cookie) {
cookie.setMaxAge(-1);
String contextPath = null;
if (!connector.getEmptySessionPath() && (getContext() != null)) {
contextPath = getContext().getEncodedPath();
}
if ((contextPath != null) && (contextPath.length() > 0)) {
cookie.setPath(contextPath);
} else {
cookie.setPath("/");
}
if (isSecure()) {
cookie.setSecure(true);
}
}
cookie.setMaxAge(-1);使COOKIE在瀏覽器被關閉時刪除。並且這裏的cookie和上面SERVLET裏的cookie都是javax.servlet.http.Cookie。
由此得出結論:
可能最開始是我理解錯了,COOKIE並無會話COOKIE和持久COOKIE之分。咱們本地建立的「持久COOKIE」和WEB容器建立的「會話 COOKIE」都是一種COOKIE,就是javax.servlet.http.Cookie。只是WEB容器把存活期設置成了關閉瀏覽器時刪除而已 (TOMCAT)。
這個結論不正確。在服務器端設置過時時間後就是持久cookie了,因此有會話COOKIE和持久COOKIE之分。
************************************************************************
cookie和session機制之間的區別與聯繫
具體來講cookie機制採用的是在客戶端保持狀態的方案。它是在用戶端的會話狀態的存貯機制,他須要用戶打開客戶端的cookie支持。cookie的做用就是爲了解決HTTP協議無狀態的缺陷所做的努力.
而session機制採用的是一種在客戶端與服務器之間保持狀態的解決方案。同時咱們也看到,因爲採用服務器端保持狀態的方案在客戶端也須要保存一個標 識,因此session機制可能須要藉助於cookie機制來達到保存標識的目的。而session提供了方便管理全局變量的方式
session是針對每個用戶的,變量的值保存在服務器上,用一個sessionID來區分是哪一個用戶session變量,這個值是經過用戶的瀏覽器在訪問的時候返回給服務器,當客戶禁用cookie時,這個值也可能設置爲由get來返回給服務器。
就安全性來講:當你訪問一個使用session 的站點,同時在本身機子上創建一個cookie,建議在服務器端的SESSION機制更安全些.由於它不會任意讀取客戶存儲的信息。
正統的cookie分發是經過擴展HTTP協議來實現的,服務器經過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie
從網絡服務器觀點看全部HTTP請求都獨立於先前請求。就是說每個HTTP響應徹底依賴於相應請求中包含的信息
狀態管理機制克服了HTTP的一些限制並容許網絡客戶端及服務器端維護請求間的關係。在這種關係維持的期間叫作會話(session)。
Cookies是服務器在本地機器上存儲的小段文本並隨每個請求發送至同一個服務器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie規範。網絡服務器用HTTP頭向客戶端發送cookies,在客戶終端,瀏覽器解析這些cookies並將它們保存爲一個本地文件,它 會自動將同一服務器的任何請求縛上這些cookies
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
理解session機制
session機制是一種服務器端的機制,服務器使用一種相似於散列表的結構(也可能就是使用散列表)來保存信息。
當程序須要爲某個客戶端的請求建立一個session的時候,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識 - 稱爲 session id,若是已包含一個session id則說明之前已經爲此客戶端建立過session,服務器就按照session id把這個 session檢索出來使用(若是檢索不到,可能會新建一個),若是客戶端請求不包含session id,則爲此客戶端建立一個session而且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個 session id將被在本次響應中返回給客戶端保存。
保存這個session id的方式能夠採用cookie,這樣在交互過程當中瀏覽器能夠自動的按照規則把這個標識發揮給服務器。通常這個cookie的名字都是相似於 SEEESIONID,而。好比weblogic對於web應用程序生成的cookie,JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是 JSESSIONID。
因爲cookie能夠被人爲的禁止,必須有其餘機制以便在cookie被禁止時仍然可以把session id傳遞迴服務器。常常被使用的一種技術叫作URL重寫,就是把session id直接附加在URL路徑的後面,附加方式也有兩種,一種是做爲URL路徑的附加信息,表現形式爲http://..... /xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另外一種是做爲查詢字符串附加在URL後面,表現形式爲http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
這兩種方式對於用戶來講是沒有區別的,只是服務器在解析的時候處理的方式不一樣,採用第一種方式也有利於把session id的信息和正常程序參數區分開來。
爲了在整個交互過程當中始終保持狀態,就必須在每一個客戶端可能請求的路徑後面都包含這個session id。
另外一種技術叫作表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。好比下面的表單
<form name="testform" action="/xxx">
<input type="text">
</form>
在被傳遞給客戶端以前將被改寫成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
這種技術如今已較少應用,筆者接觸過的很古老的iPlanet6(SunONE應用服務器的前身)就使用了這種技術。
實際上這種技術能夠簡單的用對action應用URL重寫來代替。
在談論session機制的時候,經常聽到這樣一種誤解「只要關閉瀏覽器,session就消失了」。其實能夠想象一下會員卡的例子,除非顧客主動 對店家提出銷卡,不然店家絕對不會輕易刪除顧客的資料。對session來講也是同樣的,除非程序通知服務器刪除一個session,不然服務器會一直保 留,程序通常都是在用戶作log off的時候發個指令去刪除session。然而瀏覽器歷來不會主動在關閉以前通知服務器它將要關閉,所以服務器根本不會有機會知道瀏覽器已經關閉,之所 以會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個 session id就消失了,再次鏈接服務器時也就沒法找到原來的session。若是服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的 HTTP請求頭,把原來的session id發送給服務器,則再次打開瀏覽器仍然可以找到原來的session。
偏偏是因爲關閉瀏覽器不會致使session被刪除,迫使服務器爲seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就能夠認爲客戶端已經中止了活動,纔會把session刪除以節省存儲空間。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
由JSESSIONID談cookie與SESSION的區別和聯繫
在一些投票之類的場合,咱們每每由於公平的原則要求每人只能投一票,在一些WEB開發中也有相似的狀況,這時候咱們一般會使用COOKIE來實現,例如以下的代碼:
< % cookie[]cookies = request.getCookies();
if (cookies.lenght == 0 || cookies == null)
doStuffForNewbie();
//沒有訪問過
}
else
{
doStuffForReturnVisitor(); //已經訪問過了
}
% >
這是很淺顯易懂的道理,檢測COOKIE的存在,若是存在說明已經運行過寫入COOKIE的代碼了,然而運行以上的代碼後,不管什麼時候結果都是執行 doStuffForReturnVisitor(),經過控制面板-Internet選項-設置-察看文件卻始終看不到生成的cookie文件,奇怪, 代碼明明沒有問題,不過既然有cookie,那就顯示出來看看。
cookie[]cookies = request.getCookies();
if (cookies.lenght == 0 || cookies == null)
out.println("Has not visited this website");
}
else
{
for (int i = 0; i < cookie.length; i++)
{
out.println("cookie name:" + cookies[i].getName() + "cookie value:" +
cookie[i].getValue());
}
}
運行結果:
cookie name:JSESSIONID cookie value:KWJHUG6JJM65HS2K6 爲何會有cookie呢,你們都知道,http是無狀態的協議,客戶每次讀取web頁面時,服務器都打開新的會話,並且服務器也不會自動維護客戶的上下 文信息,那麼要怎麼才能實現網上商店中的購物車呢,session就是一種保存上下文信息的機制,它是針對每個用戶的,變量的值保存在服務器端,經過 SessionID來區分不一樣的客戶,session是以cookie或URL重寫爲基礎的,默認使用cookie來實現,系統會創造一個名爲 JSESSIONID的輸出cookie,咱們叫作session cookie,以區別persistent cookies,也就是咱們一般所說的cookie,注意session cookie是存儲於瀏覽器內存中的,並非寫到硬盤上的,這也就是咱們剛纔看到的JSESSIONID,咱們一般情是看不到JSESSIONID的,但 是當咱們把瀏覽器的cookie禁止後,web服務器會採用URL重寫的方式傳遞Sessionid,咱們就能夠在地址欄看到 sessionid=KWJHUG6JJM65HS2K6之類的字符串。
明白了原理,咱們就能夠很容易的分辨出persistent cookies和session cookie的區別了,網上那些關於二者安全性的討論也就一目瞭然了,session cookie針對某一次會話而言,會話結束session cookie也就隨着消失了,而persistent cookie只是存在於客戶端硬盤上的一段文本(一般是加密的),並且可能會遭到cookie欺騙以及針對cookie的跨站腳本攻擊,天然不如 session cookie安全了。
一般session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的sessionid,這樣咱們信息共享的目的就達不到 了,此時咱們能夠先把sessionid保存在persistent cookie中,而後在新窗口中讀出來,就能夠獲得上一個窗口SessionID了,這樣經過session cookie和persistent cookie的結合咱們就實現了跨窗口的session tracking(會話跟蹤)。
在一些web開發的書中,每每只是簡單的把Session和cookie做爲兩種並列的http傳送信息的方式,session cookies位於服務器端,persistent cookie位於客戶端,但是session又是以cookie爲基礎的,明白的二者之間的聯繫和區別,咱們就不難選擇合適的技術來開發web service了。
本文來自CSDN博客,http://blog.csdn.net/yuhua3272004/archive/2009/07/17/4357268.aspx