用戶使用瀏覽器訪問服務器資源進行會話時會產生各種數據,有些數據需要將其保存下來。有的數據保存在用戶磁盤下[cookie],而有的時候需要將這些數據保存在服務器上。這個保存在服務器上的會話管理技術就是session。
一,瀏覽器中的session
在web系統中,服務器可以爲每個瀏覽器創建一個session對象,我們可以將數據保存在這個session中,這樣就可以在用戶訪問服務器其它資源的時候就可以從這個session取出這個數據。服務器默認只會給瀏覽器創建一個session對象。
二,session的創建過程
1,session是如何來爲用戶服務的?
當服務器中的servlet執行request.getSession();時如果沒有JsessionID或沒有id相匹配的session時會創建一個session同時生產一個id並將這個id存到cookie寫到用戶瀏覽器中。當用戶再次訪問服務器時就會帶上這個cookie的id.此時服務器在用這個id與內存中的session進行匹配。匹配成功即可使用這個session來服務。
session的創建過程代碼實現如下:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
//當沒有id匹配內存session時創建session
HttpSession session = request.getSession();
PrintWriter writer = response.getWriter();
if(session.isNew()){
writer.write("第一次創建session:"+session.getId());
}else{
writer.write("非第一次創建:"+session.getId());
}
}
第一次執行結果如下
再次執行結果如下:
這樣session的創建過程就說完了
三,session域對象
session是一個域對象,與之id相配時就能共享它的數據。範圍比request大。只要能取到對應的id即便重新發起請求也能共享數據。
域對象就是一個保存數據的區域,開頭說過session是一個能將用戶數據保存在服務器內存中的一個對象。說到數據保存的對象就要知道如何往裏面進行數據的增刪改查了。
域對象通用方法
方法 | 返回值 | 描述 |
---|---|---|
setAttribute(String key,Object value) | void | 將數據以鍵值對的形式保存在對象中 |
getAttribute(String key) | Objcet | 根據存入的key 來獲取對應的值 |
removeAttribute(String key) | void | 根據key來刪除對應的值 |
四,session生命週期.
1,session的創建
當服務器第一次執行request.getSession()或者執行這句話沒有與之相匹配的id時創建一個Session.
2,Session的銷燬
(1)session默認30分鐘不使用時銷燬。注意是不使用,也就是你在30分鐘內不掛機的話它就不會自動銷燬。可以通過以下兩種方式設置有效時間
使用以下這個方法:
方法 | 描述 |
---|---|
setMaxInactiveInterval(int secone) | 設置當前獲取的這個session的有效時間,單位爲秒 |
或者在web.xml配置
<session-config>
<!--配置全局session有效時間,單位爲分鐘-->
<session-timeout>10</session-timeout>
</session-config>
兩種方法同時使用時,setMaxInactiveInterval()優先級更高,它設置的是當前獲取的session的有效時間.
(2)手動執行invalidate()方法時session銷燬
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
HttpSession session = request.getSession();
//設置當前獲取的session的有效時間
session.setMaxInactiveInterval(20);
//手動銷燬session
session.invalidate();
}
五,關於瀏覽器關閉後session失效問題
1,創建session後關閉瀏覽器然後馬上重新打開重新訪問時會再次創建session。原因有兩個:
(1)session剛好過期了
(2)session沒過期,只是關閉瀏覽器後cookie被銷燬導致再次打開瀏覽器後訪問服務器時沒有攜帶對應的JSESSIONID導致無法匹配從而重新創建。即瀏覽器關閉時session並沒有被銷燬只是獲取不到它的id導致這個session永遠無法訪問到。但這個session不會一直佔用內存,過期後自動銷燬
2,那麼要如何來解決關閉瀏覽器後就無法獲取JSESSIONID的問題?
(1)自定義一個Cookie以JSESSIONID爲值,id是值。並設置有效時間添加到瀏覽器中
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
HttpSession session = request.getSession();
//自定義Cookie來將id保存起來,並設置有效時間.
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(session.getMaxInactiveInterval());
response.addCookie(cookie);
}
然後訪問該資源後效果如下:
這樣就能處理關閉瀏覽器後session失效的問題。不過這樣做的話這個sessionId的有效期就真的只有30分鐘(默認時間)。30分鐘後無論你是否關閉瀏覽器此session你都訪問不到了。因爲沒id了。但是在這30分鐘內你不管怎麼關閉瀏覽器都能再次訪問到該session。因此我們很少用session來做這種類似Cookie的本地持久化保存。因爲麻煩。而且cookie要是被禁用這個方法就沒用了。在那種情況就只能藉助數據庫。所以session做臨時緩存是很適合的。做持久化還是不容易。坑有點大。