java-servlet-cookie&sessions
http協議是無狀態協議
無狀態協議的意思是服務端與客戶端不會記錄任何一次通訊的資訊
服務端”和“客戶端”,雖然見過很多面,但每次見面仍還是認不出對方,都是陌生人。
但是,有時候認出使用者是必須的,如在使用者使用者登入時,必須能記住使用者的登入狀態。
session與cookie就是為解決http無狀態導致的問題引入的。
session
客戶端請求服務端,服務端會為這次請求開闢一塊記憶體空間,這個物件便是 Session 物件,儲存結構為ConcurrentHashMap。Session 彌補了 HTTP 無狀態特性,伺服器可以利用 Session 儲存客戶端
在同一個會話期間的一些操作記錄。
服務端的使用者資訊儲存,,等到下次連線的時候,可以檢視這個資訊,例如:
cookie:
服務端君”根據什麼去查字條呢?這就需要cookie
cookie由伺服器生成,傳送給瀏覽器,瀏覽器吧cookie以K-V的形式寫入到文字檔案內,下一次請求統一網址
會把給cookie傳送給伺服器
服務端儲存在客戶端的使用者資訊
服務端”寫了張條子交給“客戶端”,讓它下次見面時帶來
第二次識別過程:
服務端”根據客戶端君帶來的條子裡的序號,翻翻自己的口袋,找出對應的字條,就能識別出眼前的這位“客戶端”
服務端”給“客戶端”的條子就是cookie,
條子的內容就是session ID。
cookie和session的區別
session是存在伺服器端,cookie是存在客戶端,所以session的安全性比cookie高
獲取session裡的資訊是通過存放在會話cookie裡的sessin id獲取。
客戶端只要訪問的時候在請求頭帶上sessin id就可以了。
session是存放伺服器記憶體中,所以資料不斷增加早餐伺服器的負載,所以會把很重要的資訊儲存session中,
次要的資訊存放在客戶端
Token
token是多使用者下處理認證的最佳方式
無狀態 可擴充套件
支援移動裝置
跨程式呼叫
安全
基於伺服器的驗證
token生成的過程:
session如何判斷是否是為統一會話
1111伺服器第一次接收到請求時,開闢了一塊 Session 空間(建立了Session物件),同時生成一個 sessionId 2222通過響應頭的 Set-Cookie:JSESSIONID=XXXXXXX 命令,向客戶端傳送要求設定 Cookie 的響應 3333客戶端收到響應後,在本機客戶端設定了一個 JSESSIONID=XXXXXXX 的 Cookie 資訊,該 Cookie 的
過期時間為瀏覽器會話結束。
流程圖:
接下來客戶端每次向同一個網站傳送請求時,請求頭都會帶上該 Cookie 資訊(包含 sessionId ), 然後,伺服器通過讀取請求頭中的 Cookie 資訊,獲取名稱為 JSESSIONID 的值,得到此次請求的 sessionId。
Cookie記錄使用者訪問次數:
Java中把Cookie封裝成了javax.servlet.http.Cookie類。每個Cookie都是該Cookie類的物件。
可以通過操作Cookie物件對客戶端Cookie進行操作。
java獲取cookie方法 request.getCookie()獲取客戶端提交的所有Cookie(以Cookie[]陣列形式返回)
通過response.addCookie(Cookiecookie)向客戶端設定Cookie
Cookie物件使用key-value屬性對的形式儲存使用者狀態,一個Cookie物件儲存一個屬性對,一個request或者response同時使用多個Cookie
Cookie不可跨域名性
根據Cookie規範,瀏覽器訪問Google只會攜帶Google的Cookie,而不會攜帶Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。
Cookie在客戶端是由瀏覽器來管理的。瀏覽器能夠保證Google只會操作Google的Cookie而不會操作Baidu的Cookie,
從而保證使用者的隱私安全。瀏覽器判斷一個網站是否能操作另一個網站Cookie的依據是域名。Google與Baidu的域名不一樣,
因此Google不能操作Baidu的Cookie。
Cookie的Unicode編碼,儲存中文
中文與英文字元不同,中文屬於Unicode字元,在記憶體中佔4個字元,而英文屬於ASCII字元,記憶體中只佔2個位元組。Cookie中使用Unicode字元時需要對Unicode字元進行編碼,否則會亂碼。
Cookie的屬性
屬 性 名 |
描 述 |
String name |
該Cookie的名稱。Cookie一旦建立,名稱便不可更改 |
Object value |
該Cookie的值。如果值為Unicode字元,需要為字元編碼。如果值為二進位制資料,則需要使用BASE64編碼 |
int maxAge |
該Cookie失效的時間,單位秒。如果為正數,則該Cookie在maxAge秒之後失效。如果為負數,該Cookie為臨時Cookie,關閉瀏覽器即失效,瀏覽器也不會以任何形式儲存該Cookie。如果為0,表示刪除該Cookie。預設為–1 |
boolean secure |
該Cookie是否僅被使用安全協議傳輸。安全協議。安全協議有HTTPS,SSL等,在網路上傳輸資料之前先將資料加密。預設為false |
String path |
該Cookie的使用路徑。如果設定為“/sessionWeb/”,則只有contextPath為“/sessionWeb”的程式可以訪問該Cookie。如果設定為“/”,則本域名下contextPath都可以訪問該Cookie。注意最後一個字元必須為“/” |
String domain |
可以訪問該Cookie的域名。如果設定為“.google.com”,則所有以“google.com”結尾的域名都可以訪問該Cookie。注意第一個字元必須為“.” |
String comment |
該Cookie的用處說明。瀏覽器顯示Cookie資訊的時候顯示該說明 |
int version |
該Cookie使用的版本號。0表示遵循Netscape的Cookie規範,1表示遵循W3C的RFC 2109規範 |
Servlet Cookie的使用方法
設定Cookie的域名domain:
正常情況下,同一個一級域名下的兩個二級域名如www.helloweenvsfei.com和images.helloweenvsfei.com也不能互動使用Cookie,因為二者的域名並不嚴格相同。
如果需要共同使用該Cookie
需要設定Cookie的domain引數,例如:
cookie.setDomain(".helloweenvsfei.com"); // 設定域名
設定Cookie的路徑
domain屬性決定執行訪問Cookie的域名,而path屬性決定允許訪問Cookie的路徑(ContextPath)。
如果只允許/quan/路徑下的程式使用Cookie
cookie.setPath("/quan/");
設定為“/”時允許所有路徑使用Cookie。path屬性需要使用符號“/”結尾
注意:頁面只能獲取它屬於的Path的Cookie。例如/session/test/a.jsp不能獲取到路徑為/session/abc/的Cookie。
設定Cookie的安全性
secure屬性並不能對Cookie內容加密,因而不能保證絕對的安全性。如果需要高安全性,需要在程式中對Cookie內容加密、解密,以防洩密。
Session的生命週期:
Session儲存在伺服器端。為了獲得更高的存取速度,伺服器一般把Session放在記憶體裡。每個使用者都會有一個獨立的Session。如果Session內容過於複雜,當大量客戶訪問伺服器時可能會導致記憶體溢位。因此,Session裡的資訊應該儘量精簡。
只訪問HTML、IMAGE等靜態資源並不會建立Session
Session的有效期:
防止記憶體溢位,伺服器會把長時間內沒有活躍的Session從記憶體刪除。這個時間就是Session的超時時間。如果超過了超時時間沒訪問過伺服器,Session就自動失效了。
Session的超時時間為maxInactiveInterval屬性,可以通過對應的getMaxInactiveInterval()獲取,
通過setMaxInactiveInterval(longinterval)修改。
Session的超時時間也可以在web.xml中修改。另外,通過呼叫Session的invalidate()方法
可以使Session失效。
Session常用方法:
方 法 名 |
描 述 |
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.get CreationTime()) |
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失效 |