HttpSession伺服器端會話技術
①什麼是session?
session是伺服器端技術,利用這個技術,伺服器在執行時可以為每一個瀏覽器建立一個共享的session物件,由於
session為使用者瀏覽器獨享,所以當瀏覽器訪問伺服器的web資源時,可以把各自的資料放在各自的session中,當用戶
再去訪問伺服器中的其它web資源時,其它web資源再從使用者各自的session中取出資料為使用者服務。
②session是如何建立的呢?
當用戶開啟瀏覽器,訪問某個站點時操作session時,伺服器就會查詢改伺服器記憶體中有沒有建立該session物件,如果已經建立那麼就通過sessionid值到web伺服器中找到該session並使用,如果沒有web伺服器就會為該瀏覽器分配一個獨享的session,為這個session設定一個sessionid標識,sessionid中包含了瀏覽器資訊和session所屬於web伺服器下的web應用,然後將sessionid封裝到response物件中響應給客戶端,客戶端將該值儲存到cookie中,然後客戶端在發出請求時會將該web應用下的cookie都帶給web伺服器,當要呼叫session時就通過cookie來找到對應的session。這裡要注意的是session是客戶端與伺服器進行資料共享的一個物件,session雖然儲存在web伺服器記憶體中,並且與一個瀏覽器綁定了。但是web伺服器下如果有多個web站點,預設情況下同一個瀏覽器訪問一個web伺服器下的不同web站點建立的是不同的session物件。伺服器是如何實現一個瀏覽器在一個web應用下對應一個session如下圖:
③session的生命週期預設是30分鐘這個可以在web.xml檔案中看到其配置的預設時間,也可以通過修改配置來設定session的生命週期。web伺服器設定session的預設生命週期如圖:
當然如果你修改的是web伺服器的web.xml就會對所有web伺服器下的所有web應用建立的session的生命週期生效。
如果你修改的是web應用的web.xml就會對當前web應用建立的session的生命週期生效。如果衝突了那麼以web應用下設定的優先順序更高。
當然還有兩個函式可以影響session的生命週期
setInactiveInterval():Specifies the time, in seconds, between client requests before the servlet container will invalidate this session。指的是具體的時間引數是設定servlet容器將使session失效在客戶端請求之前。也就是說 這個時間是設定session懶散的時間,在此時間中session沒有被訪問將會失效,如果被訪問了那麼就重置time值再次進入懶散狀態。
Invalidate():Invalidates this session then unbinds any objects bound to it.
使這個session失效並且使session中繫結的物件都失效。
④session是一個域物件,其資料機構相當於一個map,也是以鍵值對的形式儲存資料的。session中可以存放任何Object物件。同樣在session中儲存鍵名重複的值時,該值會被覆蓋。
⑤上面我們已經說過session是儲存在伺服器端的,session在一次會話中有效,那麼我們在關閉瀏覽器後,伺服器於該瀏覽器關聯的session有沒有自動銷燬呢?當然是沒有,因為session儲存在web伺服器端,當瀏覽器關閉時,瀏覽器不會發送請求給web伺服器,所以session還是在生命週期沒有結束時,依然存在於web伺服器的記憶體中。那麼也就是說在session生命週期還沒有結束時,我們關閉瀏覽器,再開啟瀏覽器訪問web伺服器下的web應用,該session仍然是存在的。那麼我們如何來獲得這個之前被我的瀏覽器獨享的session呢?其實很簡單,因為把session和瀏覽器進行繫結的就是一個JSESSIONID的cookie,也就是說我們在第一次呼叫該session時就建立一個cookie鍵名為JSESSIONID的cookie並且把生命週期設定為和session的一樣,然後通過response物件響應給瀏覽器,瀏覽器做儲存這樣每次瀏覽器傳送請求都會帶上這個cookie。這樣就可以實現我們以上關閉瀏覽器再開啟瀏覽器時,仍然能
訪問之前瀏覽器獨享的session。這裡需要理解cookie的相關知識。如有不理解可以看看我之前寫的cookie的總結:
http://blog.csdn.net/nihaowoshiyudong/article/details/53535183
java程式碼如下:
①建立session並且儲存了JSESSIONID的cookie
package com.yd.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class CreateSession
*/
@WebServlet("/CreateSession")
public class CreateSession extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CreateSession() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//第一次獲得session時建立該session
HttpSession session=request.getSession();
session.setAttribute("name", "TomCat");
//儲存JSESSIONID這個cookie使其和session的生命週期一樣
Cookie cookie=new Cookie("JSESSIONID", session.getId());
//設定cookie的生命週期
cookie.setMaxAge(30*60);
response.addCookie(cookie);
//response.sendRedirect("/SessionTest/GetSessionServlet");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
瀏覽器接受的響應頭如圖:
②關閉瀏覽器
③再次開啟瀏覽器傳送請求同一web應用下的資源,java程式碼如下:
package com.yd.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class GetSessionServlet
*/
@WebServlet("/GetSessionServlet")
public class GetSessionServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public GetSessionServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲得session中的屬性
request.setCharacterEncoding("utf-8");
HttpSession session=request.getSession();
String name=(String) session.getAttribute("name");
System.out.println("關閉瀏覽器後顯示的session內容:"+name+"id值"+session.getId());
//顯示的結果
//關閉瀏覽器後顯示的session內容:TomCat id值8B49F6CBD34BFDDEE43BA58912FA65D9
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
請求資訊頭如下:
可見請求資訊頭的JSESSIONID和響應資訊頭的JSESSIONID的值一樣。所以通過JSESSIONID就能找到瀏覽器獨享的session,無論是否是一次會話,只要session生命週期沒有結束,都可以訪問到該session。