WEB開發會話技術03
10.問題引出
-
問題引出
- 不同的用戶登錄網站后,不管該用戶瀏覽網站的哪個頁面,都可以顯示登錄人的名字,還可以隨時去查看自己購物車中的商品,這是如何實作的呢?
- 也就是說,一個用戶在瀏覽一個網站的不同頁面時,服務器是如何知道是張三在瀏覽這個頁面,還是李四在瀏覽這個頁面?
-
解決方法1- 使用cookie
在用戶登錄的時候,服務器可以將用戶資訊通過cookie的形式保留在瀏覽器,每當用戶訪問不同的網頁(發送HTTP請求),瀏覽器都會將該cookie發送給服務器,服務器通過獲取cookie的值,在網頁上就可以顯示當前用戶的資訊;同時服務器也可以通過cookie(用戶資訊)找到用戶操作用戶在資料庫中對應的資料,
但是使用cookie會存在以下問題:第一是cookie不能存放大的資料;第二是cookie不安全,不能存放敏感資訊;第三,cookie不是跟一個用戶關聯的,如果一個cookie是長期保存的,那么當其他人打開瀏覽器時,也可以登錄你的賬號,因此單單使用cookie來實作也不太理想,
-
解決方法2- 使用session
session是服務器端的技術,也就是說session的資料是保存在服務器端的,服務器在運行時會為每一個用戶的瀏覽器創建一個其獨享的session物件(該物件可以理解為一個集合),
由于session為每個用戶瀏覽器獨享,所以用戶在訪問服務器的不同頁面時,可以從各自的session中讀取/添加資料,從而完成任務,
11.Session基本介紹

-
當用戶打開瀏覽器,訪問某個網站,操作session時,服務器就會在記憶體(在服務端)為該瀏覽器分配一個session物件,該session物件被這個瀏覽器獨占,如上圖
-
這個session物件也可以看做是一個容器/集合,session物件默認存在的時間為30min(在tomcat/conf/web.xml中可以修改)
11.1session可以做什么
- 網上商城的購物車
- 保存登錄用戶的資訊
- 將資料放入到Session中,供用戶在訪問不同頁面時,實作跨頁面訪問資料
- 防止用戶非法登錄到某個頁面
- .......
11.2如何理解session
-
session存盤結構示意圖
-
你可以把session看做是一容器(類似HashMap),有兩列(k-v),每一行就是session的一個屬性
-
每個屬性包含有兩個部分,一個是該屬性的名字(String),一個是該屬性的值(Object)
12.Session常用方法
-
創建和獲取session(api一樣)
HttpSession session = request.getSession();第一次呼叫是創建Session會話,之后呼叫是獲取創建好的Session物件
-
向session添加屬性
session.setAttribute(String name,Object val); -
從session得到某個屬性
Object obj = session.getAttribute(String name); -
從session洗掉某個屬性
session.removeAttribute(String name); -
isNew(); 判斷是不是剛創建出來的Session
-
每個Session都有一個唯一標識的Id值(即JSESSIONID),通過getId()得到Session的會話Id值
13.Session底層實作機制
13.1原理分析圖
整個程序如下:
一個瀏覽器向服務器發送請求,要操作session時,一定會呼叫request.getSession()方法,
- 這個方法會先判斷瀏覽器是否攜帶了JSESSIONID的cookie:
- 如果沒有攜帶,就會在服務器記憶體中創建一個session物件,并且為這個session分配一個sessionId,如上圖,可以理解為服務器記憶體有一個map<String,Object>,sessionId作為map的key,session物件作為key關聯的value,如此,這個sessionId就和該session物件關聯起來了,
- 如果攜帶了,就會進一步判斷:判斷服務端的map中是否已經存在了該JSESSIONID對應的session物件
- 如果map中沒有,就會創建一個session物件,并且為這個session分配一個新的sessionId,
- 如果map中已經存在了該JSESSIONID對應的session物件,就直接操作,
如果服務器在本次會話中,創建了session,則在回應頭中將以Set-Cookie:JSESSIONID=xxxx的形式回傳一個cookie給瀏覽器保存,下一次瀏覽器發送請求時,服務器就可以拿到cookie中的JSESSIONID的值,在map中找到該瀏覽器對應的session,直接操作,
這里的map可以理解為在Tomcat中還維護了一個容器HashMap<String,HttpSession>,這個容器中以JSESSIONID為key,以session為value,完成兩者的系結,
13.2代碼演示
演示Session底層實作機制-創建和讀取Session
13.2.1創建session的實體分析
web.xml:
<servlet>
<servlet-name>CreateSession</servlet-name>
<servlet-class>com.li.session.CreateSession</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CreateSession</servlet-name>
<url-pattern>/createSession</url-pattern>
</servlet-mapping>
CreateSession:
package com.li.session;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class CreateSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//System.out.println("CreateSession doPost被呼叫...");
//1.獲取session(同時也可能創建session)
HttpSession session = request.getSession();//注意這個地方已經把sessionId分配了
//2.給session獲取id
System.out.println("當前sessionid= " + session.getId());
//3.給session存放一些資料
session.setAttribute("email", "[email protected]");
//4.給瀏覽器發送一個回復
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>創建/操作session成功...</h1>");
writer.flush();
writer.close();
}
}
-
首先訪問
http://localhost:8080/cs/createSession:
-
抓包顯示:
走的是如下流程:
-
服務器后端顯示:
-
此時瀏覽器存盤的JSESSIONID變成了新的值:
-
此時,如果再次訪問服務器,就會攜帶cookie中新的jsessionid給服務器,服務器不再回傳jsessionid,
? 走的是如下流程:
-
如果redeployTomcat,關閉瀏覽器并重新打開,直接訪問
http://localhost:8080/cs/createSession,這時候的請求頭將不會攜帶jsessionid(因為關閉瀏覽器時默認洗掉了cookie),服務器回傳的回應頭將會攜帶一個jsessionid(因為重新發布tomcat,會清空服務器記憶體,這時請求的資源createSession程式會創建一個session,因此服務器會回傳一個與之關聯的jsessionid)這時候走的就是如下流程:
13.2.2讀取session的實體分析
web.xml:
<servlet>
<servlet-name>ReadSession</servlet-name>
<servlet-class>com.li.session.ReadSession</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ReadSession</servlet-name>
<url-pattern>/readSession</url-pattern>
</servlet-mapping>
ReadSession:
package com.li.session;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class ReadSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//System.out.println("ReadSession doPost被呼叫...");
//演示讀取session
//1.獲取session,如果沒有session也會創建
HttpSession session = request.getSession();
//2.給session獲取id
System.out.println("ReadSession 當前sessionid= " + session.getId());
//3.讀取屬性
Object email = session.getAttribute("email");
if (email != null) {
System.out.println("session屬性 email= " + (String) email);
} else {
System.out.println("session中沒有 email屬性");
}
//3.給瀏覽器發送一個回復
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>讀取session成功...</h1>");
writer.flush();
writer.close();
}
}
-
redeployTomcat,首先在瀏覽器中訪問
http://localhost:8080/cs/createSession(目的是創建一個和瀏覽器關聯的session,因為redeployTomcat會洗掉服務器的session) -
然后訪問
http://localhost:8080/cs/readSession,并抓包:
-
在服務器后臺輸出如下:第一行輸出是我們創建session時獲取的sessionid,第二行是我們讀取session時獲取的sessionid,并獲取其屬性,
14.Session生命周期
-
public void setMaxInactiveInterval(int interval):設定session的超時時間(以秒為單位),超過指定的時長,session就會被銷毀, -
值為正數的時候,設定session的超時時長,
-
值為負數時,表示永不超時
-
public int getMaxInactiveInterval()表示獲取session的超時時間 -
public void invalidate()表示讓當前的session會話立即無效 -
如果沒有呼叫
setMaxInactiveInterval(int interval)來指定session的生命時長,Tomcat會以session的默認時長為準,session的默認時長為30分鐘,可以在tomcat目錄的conf目錄下的web.xml中設定,
-
Session的生命周期指的是:客戶端兩次請求的最大間隔時長,而不是累積時長,即當客戶端訪問了自己的session,session的生命周期將將從0開始重新計算,(指的是同一個會話兩次請求之間的間隔時間)
cookie的生命周期指的是累積時長
-
底層:Tomcat用一個執行緒來輪詢會話狀態,如果某個會話的空閑時間超過設定的最大值,則將該會話銷毀,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/538019.html
標籤:其他
上一篇:第2-4-1章 規則引擎Drools介紹-業務規則管理系統-組件化-中臺
下一篇:富文本中提取文本的方法分享
