http 是無狀態的,session與cookie是爲了保持訪問用戶與後端服務器的交互狀態。java
具體來講cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在服務器端保持狀態的方案。因爲採用服務器端保持狀態的方案在客戶端也須要保存一個標識,因此session機制可能須要藉助於cookie機制來達到保存標識的目的,session經過cookie,在客戶端保存session id,而將用戶的其餘會話消息保存在服務端的session對象中,與此相對的,cookie須要將全部信息都保存在客戶端。所以cookie存在着必定的安全隱患.web
cookie機制。正統的cookie分發是經過擴展HTTP協議來實現的,服務器經過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。而cookie的使用是由瀏覽器按照必定的原則在後臺自動發送給服務器的。瀏覽器檢查全部存儲的cookie,若是某個cookie所聲明的做用範圍大於等於將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器。後端
要說cookie的生命週期,首先得理解一次會話,會話可簡單理解爲:用戶開一個瀏覽器,點擊多個超連接,訪問服務器多個web資源,而後關閉瀏覽器,整個過程稱之爲一個會話。跨域
cookie在不設置有效期時,默認爲一次會話,關閉瀏覽器窗口,cookie就消失。會話cookie通常不存儲在硬盤上而是保存在內存裏,固然這種行爲並非規範規定的 , 若設置了過時時間,瀏覽器就會把cookie保存到硬盤上,關閉後再次打開瀏覽器,這些cookie仍然有效直到超過設定的過時時間。存儲在硬盤上的cookie能夠在不一樣的瀏覽器進程間共享。瀏覽器
要想在cookie中存儲中文,那麼必須使用URLEncoder類裏面的encode(String s, String enc)方法進行中文轉碼,例如:安全
1 Cookie cookie = new Cookie("userName", URLEncoder.encode("孤傲蒼狼", "UTF-8")); 2 response.addCookie(cookie);
在獲取cookie中的中文數據時,再使用URLDecoder類裏面的decode(String s, String enc)進行解碼,例如:服務器
1 URLDecoder.decode(cookies[i].getValue(), "UTF-8")
session機制是一種服務器端的機制,服務器使用一種相似於散列表的結構(也可能就是使用散列表)來保存信息。但程序須要爲某個客戶端的請求建立一個session的時候,服務器首先檢查這個客戶端的請求裏是否包含了一個session標識-稱爲session id,若是已經包含一個session id則說明之前已經爲此客戶建立過session,服務器就按照session id把這個session檢索出來使用(若是檢索不到,可能會新建一個,這種狀況可能出如今服務端已經刪除了該用戶對應的session對象,但用戶人爲地在請求的URL後面附加上一個JSESSION的參數)。若是客戶請求不包含session id,則爲此客戶建立一個session而且同時生成一個與此session相關聯的session id,這個session id將在本次響應中返回給客戶端保存,保存這個session id的方式能夠採用cookie,這樣在交互過程當中瀏覽器能夠自動的按照規則把這個標識發揮給服務器。通常這個cookie的名字都是相似於SEEESIONID。但cookie能夠被人爲的禁止,則必須有其餘機制以便在cookie被禁止時仍然可以把session id傳遞迴服務器。
常常被使用的一種技術叫作URL重寫,就是把session id直接附加在URL路徑的後面。還有一種技術叫作表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。cookie
在程序中第一次調用request.getSession()方法時就會建立一個新的Session,能夠用isNew()方法來判斷Session是否是新建立的。session
//使用request對象的getSession()獲取session,若是session不存在則建立一個 HttpSession session = request.getSession(); //獲取session的Id String sessionId = session.getId(); //判斷session是否是新建立的 if (session.isNew()) { // }else { // }
<!-- 設置Session的有效時間:以分鐘爲單位--> <session-config> <session-timeout>15</session-timeout> </session-config>
當須要在程序中手動設置Session失效時,能夠手工調用session.invalidate方法,摧毀session。jsp
1 HttpSession session = request.getSession(); 2 //手工調用session.invalidate方法,摧毀session 3 session.invalidate();
4.3 禁用Cookie後servlet共享Session中的數據 -URL 重寫
response.encodeRedirectURL(java.lang.String url) 用於對sendRedirect方法後的url地址進行重寫。
response.encodeURL(java.lang.String url)用於對錶單action和超連接的url地址進行重寫
在使用URL重寫幾隻的時候要注意,爲了保證會話跟蹤的正確性,全部的連接和重定向語句中的URL都須要調用encodeURL()或encodeRedirectURL()方法進行編碼。另外,因爲附加在URL中的session ID是動態產生的,對每個用戶是不一樣的,因此對於靜態頁面的相互跳轉,URL重寫機制無能爲力。固然能夠經過將靜態頁面轉換爲動態頁面解決。
方法的執行:首先判斷當前的Servlet是否執行了HttpSession對象的invalidate()方法,若是已經執行返回參數URL。接下來判斷客戶端是否禁用了Cookie,沒有禁用直接返回參數URL,若是禁用,則在參數URL中附加session ID,返回編碼後的URL。
若是要使用URL重寫的方式來發送Session ID,則可使用HttpServletRequest的encodeURL()協助產生所需的URL重寫。當容器嘗試取得HttpSession實例時,若能夠從HTTP請求中取得帶有Session ID的Cookie,encodeURL()會將設置給它的URL原封不動的輸出;若沒法從HTTP請求中取得帶有Session ID的Cookie(一般是瀏覽器禁用Cookie的狀況),encodeURL()會自動產生帶有Session ID的URL重寫。
若是有執行encdeURL(),在瀏覽器第一次請求網站時,容器並不知道瀏覽器是否禁用Cookie,因此容器的作法是Cookie(發送set-cookie標頭)與URL重寫都作,所以若Servlet有如下語句,不管瀏覽器是否禁用Cookie,第一次請求時,都會顯示編上Session ID的URL。
當再次請求時,若是瀏覽器沒有禁用Cookie,則容器能夠從Cookie(從cookie標頭)中取得Session ID,此時encodeURL()就只會輸出index.jsp。若是瀏覽器禁用Cookie,則encodeURL()就會繼續在URL上編上Session ID
HttpServletResponse的另外一個方法encodeRedirectURL()方法,能夠在要去瀏覽器重定向時,在URL上編上Session ID。