cookie、session總結
前幾天在調試第三方支付接口時碰到一個session失效問題,用了幾天時間才搞明白,現在回想一下,主要還是由於cookie和session這一塊的一些基本概念沒有搞清楚,現總結一下。
瀏覽器使用HTTP協議作為應用層協議,而HTTP協議是一個無狀態協議,但是通常web站點希望能夠識別用戶,可能是因為服務器希望限制用戶的訪問,或者因為它希望把內容與用戶身份聯系起來。這就需要將瀏覽器與web服務器之間多次交互當作一個整體來處理,並且將多次交互所涉及的數據及狀態保存下來,通常有兩種方案:cookie和session。
cookie
服務器為了識別用戶身份而臨時存放在瀏覽器端的少量數據。瀏覽器器訪問服務器時,服務器將一些數據以Cookie消息頭的形式發送給瀏覽器(由程序指定),瀏覽器會將這些數據保存下來;當瀏覽器再次訪問服務器時,會將這些數據以Cookie消息頭的方式發送給服務器。
使用Cookie
//添加Cookie Cookie c = new Cookie(String name,String value); response.addCookie(c); //讀取Cookie Cookie[] request.getCookies(); String cookie.gtName() String cookie.getValue()
Cookie編碼問題
cookie只能存放合法的ascii字符,如果要存放中文,可以將中文轉換成合法的asscii字符形式,通過如下方式進行編解碼,編碼後的字符串可以存到cookie中,讀取時再進行解碼。
String URLEncoder.encode(String str,String charset); //編碼 String URLDecoder.decode(String str,String charset); //解碼
Cookie生存時間問題
可以通過cookie.setMaxAge(int seconds)來設置:
seconds>0,瀏覽器會將cookie保存在硬盤上,超過指定時間cookie失效;
seconds<0,默認值,瀏覽器會將cookie存在內存中,關閉瀏覽器後cookie失效;
seconds=0,刪除cookie;
Cookie的路徑問題
瀏覽器端保存的cookie內容主要包括:名字,值,過期時間,路徑和域名。
瀏覽器在訪問服務器上的某個地址時,會比較Cookie的路徑與該路徑是否匹配,瀏覽器只會將路徑匹配的Cookie發送給服務器。cookie的默認路徑為添加該cookie的web組件的路徑,比如/servlet/addCookie.jsp添加了一個cookie,則瀏覽器端保存該cookie對應的默認路徑為:/servlet。
在瀏覽器端一般會保存多個cookie,當瀏覽器要訪問服務器時如何決定要將哪個cookie添加至消息頭中呢?
匹配規則如下:
要訪問的地址必須是cookie的路徑或其子路徑,而且域名需一致。
比如瀏覽器端保存的cookie的路徑是/servlet/work/,當訪問/servlet/buy.jsp這個頁面時是不會將該cookie放入消息頭中的,而當訪問/servlet/work/buy.jsp或/servlet/work/flow/buy.jsp兩者之一時,瀏覽器是會將前面的cookie放入消息頭之中的。
cookie的限制
a.cookie不安全
b.cookie可以被用戶禁止
c.cookie只能保存少量數據,4k左右
d.瀏覽器保存的cookie的數量也有限制(大約幾百個)
e.cookie只能保存字符串
session(會話)
服務器端為了保存狀態而創建的一個特殊的對象。
瀏覽器訪問服務器時,服務器會創建一個特殊對象session(由程序指定,該對象有一個唯一的id,本文稱之為sessionId),服務器會將sessionId以cookie形式發送給瀏覽器;當瀏覽器再次訪問服務器時,會在消息頭中帶有包含sessionId的cookie消息頭,服務器端可以利用這個sessionId找到相應的對象,來保存一些狀態值。
使用session
//方式一
HttpSession session = request.getSession(boolean flag); //當flag為true時,先查看請求當中有沒有sessionId,如果有,則依據該sessionId查找對應的session對象,找到則返回,找不到則創建新session對象;如果請求當中沒有,則直接創捷session對象;
//當flag為false,與true類似,只是在沒有找到session對象時返回空
//方式二
HttpSession session = request.getSession(); //等價於request.getSession()
session超時
服務器會將空閑時間過長的session對象刪除掉,這樣做是為了節省內存空間的占用。服務器默認的超時時間一般是30分鐘。可以通過setMaxInactiveInterval(int seconds)來設置兩次請求之間的最大時間間隔,也可看成是失效時間,如果超過這個失效時間,則服務器會銷毀這個session對象。
使用session場景
比如登陸控制,在登陸成功後,將一些數據綁定到session對象上,如:
session.setAttribute("user",user);
當用戶請求要保護的資源(只有登陸成功才能訪問的資源)時候,進行session驗證:
Object obj = session.getAttribute("user"); if(obj == null){//沒有登陸,重定向到登陸頁面 response.sendRedirect("login.jsp)"; }
註:以上關於session和cookie的demo是在tomcat容器下測試的
cookie、session總結