什么是Session
對Tomcat而言,Session是一塊在服務器開辟的內存空間,其存儲結構為ConcurrentHashMap;
Session的目的
Http協議是一種無狀態協議,即每次服務端接收到客戶端的請求時,都是一個全新的請求,服務器并不知道客戶端的歷史請求記錄;
Session的主要目的就是為了彌補Http的無狀態特性。簡單的說,就是服務器可以利用session存儲客戶端在同一個會話期間的一些操作記錄;
實現機制
先看兩個問題,如下:
1、服務器如何判斷客戶端發送過來的請求是屬于同一個會話?
答:用Session id區分,Session id相同的即認為是同一個會話,在Tomcat中Session id用JSESSIONID表示;
2、服務器、客戶端如何獲取Session id?Session id在其之間是如何傳輸的呢?
答:服務器第一次接收到請求時,開辟了一塊Session空間(創建了Session對象),同時生成一個Session id,并通過響應頭的Set-Cookie:“JSESSIONID=XXXXXXX”命令,向客戶端發送要求設置cookie的響應;
客戶端收到響應后,在本機客戶端設置了一個JSESSIONID=XXXXXXX的cookie信息,該cookie的過期時間為瀏覽器會話結束;
接下來客戶端每次向同一個網站發送請求時,請求頭都會帶上該cookie信息(包含Session id);
然后,服務器通過讀取請求頭中的Cookie信息,獲取名稱為JSESSIONID的值,得到此次請求的Session id;
ps:服務器只會在客戶端第一次請求響應的時候,在響應頭上添加Set-Cookie:“JSESSIONID=XXXXXXX”信息,接下來在同一個會話的第二第三次響應頭里,是不會添加Set-Cookie:“JSESSIONID=XXXXXXX”信息的;
而客戶端是會在每次請求頭的cookie中帶上JSESSIONID信息;
舉個例子:
以chrome瀏覽器為例,訪問一個基于tomcat服務器的網站的時候,
瀏覽器第一次訪問服務器,服務器會在響應頭添加Set-Cookie:“JSESSIONID=XXXXXXX”信息,要求客戶端設置cookie,如下圖:

同時我們也可以在瀏覽器中找到其存儲的sessionid信息,如下圖

接下來,瀏覽器第二次、第三次...訪問服務器,觀察其請求頭的cookie信息,可以看到JSESSIONID信息存儲在cookie里,發送給服務器;且響應頭里沒有Set-Cookie信息,如下圖:

只要瀏覽器未關閉,在訪問同一個站點的時候,其請求頭Cookie中的JSESSIONID都是同一個值,被服務器認為是同一個會話。
再舉個簡單的例子加深印象,新建個Web工程,并寫一個Servlet,在doGet中添加如下代碼,主要做如下工作
首先,從session中獲取key為count的值,累加,存入session,并打印;
然后,每次從請求中獲取打印cookie信息,從響應中獲取打印Header的Set-Cookie信息:
/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if(request.getSession().getAttribute("count") == null){ request.getSession().setAttribute("count", 0); response.getWriter().write(0+""); }else{ int a = Integer.parseInt(request.getSession().getAttribute("count").toString()); request.getSession().setAttribute("count", ++a); response.getWriter().write(a+""); } Cookie[] cookies = request.getCookies(); StringBuffer sb = new StringBuffer(); if(cookies!=null){ for(Cookie cookie : cookies){ sb.append(cookie.getName()+":"+cookie.getValue()+","); } sb.deleteCharAt(sb.length()-1); } System.out.println("[第"+(++index)+"次訪問]from client request, cookies:" + sb); System.out.println("[第"+(index)+"次訪問]from server response, header-Set-Cookie:" + response.getHeader("Set-Cookie"));; }
|
新聞熱點
疑難解答