目錄
一、概念
會話技術就是客戶端和服務器之間的通信,一次會話包含多次請求和響應,從客戶端第一次給服務器發送請求開始建立會話到有一方斷開爲止。
- 功能:在一次會話的範圍內能有多次請求響應,可以實現多次請求響應之間的數據共享
- 會話方式
- 客戶端會話技術:Cookie(將數據保存在客戶端)
- 服務器會話技術:Session(將數據保存在服務器)
二、Cookie 客戶端會話技術
Cookie 客戶端會話技術既是在瀏覽器客戶端向服務器發送請求,請求完成後,服務器會攜帶一些數據相應給瀏覽器客戶端,瀏覽器客戶端會將數據保存在本地;下一次請求會攜帶者數據請求
1、Cookie 使用步驟
- 服務器創建 Cookie 對象:new Cookie(String name,String value)
- 客戶端發送 Cookie 對象:response.addCookie(Cookie cookie)
- 服務器獲取 Cookie 對象:Cookie[] response.getCookies()
2、實現原理
- 客戶端發送請求給服務器
- 服務器發送響應頭set-cookie並攜帶數據給客戶端
- 客戶端將響應頭攜帶的數據保存到客戶端瀏覽器中
- 下一次請求服務器會使用消息頭cookie數據攜帶給服務器
- 服務器獲取消息頭中的數據
3、Cookie 特點
- 一次可以創建多個 Cookie 對象
- Cookie 在瀏覽器中保存的時間問題:
- 默認情況下,當瀏覽器關閉後,Coolie 數據被銷燬
- 設置持久化數據:setMaxAge(int seconds)
- 參數爲正數時:將 Cookie 數據寫到硬盤的文件中,持久化數據,參數表示存儲的時間
- 參數爲負數時:默認就是負數,關閉瀏覽器再次打開就沒有了數據
- 參數爲零時:刪除 Cookie 數據
- 在 Tomcat8之後,Cookie 支持中文數據,但對於特殊字符如空格,需要進行URL編碼和轉碼
- URL編碼:URLEncoder.encode(str,"utf-8")
- URL解碼:URLDecoder.decode(str,"utf-8")
- 瀏覽器對於單個 Cookie 的大小有限制(4kb),對於同一個域名下的總 Cookie 數量也有限制(20個)
4、Cookie 共享問題
- 同一服務器下設置共享範圍:setPath(String path)
- 默認情況下,路徑的參數爲當前虛擬目錄,一個Tomcat服務器中的多個web項目之間的 Cookie 是不能共享的
- 如果要共享,可以將參數設置爲 “/”,即:setPath("/")
- 不同服務器下設置共享範圍:setDomain(String path)
- 如果設置同一級域名,那麼多個服務器之間的 Cookie 可以共享
- eg:setDomain(".baidu.com")
- 如果設置同一級域名,那麼多個服務器之間的 Cookie 可以共享
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//URL編碼
String str = "I love you so much!";
String URLstr = URLEncoder.encode(str,"utf-8");
//創建Cookie對象
Cookie C = new Cookie("msg",URLstr);
//持久化數據
C.setMaxAge(30); //持久化30秒
//設置共享範圍,讓當前服務器下的項目都能共享Cookie
C.setPath("/");
//發送Cookie對象
response.addCookie(C);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取Cookie
Cookie[] Cs = request.getCookies();
if(Cs != null){
for(Cookie C : Cs){
String name1 = C.getName();
String value1 = C.getValue();
//解碼
String name2 = URLDecoder.decode(name1,"utf-8");
String value2 = URLDecoder.decode(value1,"utf-8");
System.out.println(name2 + ":" + value2);
}
}
}
三、Session 服務器端會話技術
服務器端會話技術即是在一次會話的多次請求間共享數據,將數據保存在服務器端的 HTTPSession 對象中
1、獲取 HTTPSession 對象
先獲取 HTTPSession 對象:HttpSession session = request.getSession(),再調用方法
- Object getAttribute(String name)
- void setAttribute(String name,Object value)
- void removeAttribute(String name)
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取Session
HttpSession session = request.getSession();
//存儲數據
session.setAttribute("msg","oneStar");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取Session
HttpSession session = request.getSession();
//獲取數據
Object msg = session.getAttribute("msg");
System.out.println(msg);
}
2、session 特點
- session 用於存儲一次會話的多次請求的數據
- session 數據存儲在服務器中
- session 可以存儲任意類型,任意大小的數據
3、Session 會話原理
服務器如何確保在一次會話範圍內多次獲取的 Session 對象是同一個
- 瀏覽器向服務器發送請求
- 服務器響應瀏覽器並攜帶唯一標識(使用響應頭攜帶set-cookie)
- 瀏覽器再次發送請求將唯一標識攜帶給服務器(使用cookie)
- 服務器判斷瀏覽器是否攜帶唯一標識
- 若攜帶唯一標識:
- 服務器拿着唯一標識去 session 池中查詢是否有對應的標識
- 若有,則直接操作 session 對象,並把它放到瀏覽器
- 若無,服務器會爲其創建一個私有的內存空間,可以操作 session 對象,並放到瀏覽器中
- 服務器拿着唯一標識去 session 池中查詢是否有對應的標識
- 若不攜帶唯一標識:
- 服務器會爲其創建一個私有的內存空間,可以操作 session 對象,並放到瀏覽器中
- 若攜帶唯一標識:
Session 的實現是依賴於 Coolie 的
4、Session 共享問題
【1】當客戶端關閉,服務器不關閉,兩次獲取 session 是否爲同一個?
- 默認情況下不是同一個 session
- 如果需要相同,可以創建 Cookie,鍵爲 JSEEIONID,設置最大存活時間,讓 cookie 持久化存儲
- Cookie C = new Cookie("JSESSIONID",session.getID());
C.setMaxAge(60*60);
response.addCookie(C);
- Cookie C = new Cookie("JSESSIONID",session.getID());
【2】當客戶端不關閉,服務器關閉,兩次獲取的 session 是同一個嗎?
不是同一個,這樣一來會存在數據丟失,一般情況需要保證數據不丟失,可以使用鈍化和活化來解決這個問題,而Tomcat 已經幫我們做好了這一步
- session 鈍化:在服務器正常關閉之前,將 session 對象系列化到硬盤上
- session 活化:在啓動服務器之後,將 session 文件轉化爲內存中的 session 對象
注:IDEA不會執行鈍化和活化的過程,需要將項目部署到Tomcat目錄當中,即 apache-tomcat-8.5.38/webapps目錄下,臨時存儲的數據會保存在 apache-tomcat-8.5.38/work/Catalina/localhost 目錄下
5、session 銷燬時間
- 服務器關閉
- session 對象調用 invalidata() 方法
- session 默認失效時間:30分鐘
- 可以修改配置文件來修改默認失效時間(在 apache-tomcat-8.5.38/conf/web.xml 文件中),這時所有項目的父配置文件
<session-config>
<session-timeout>30</session-timeout>
</session-config>
- 可以修改配置文件來修改默認失效時間(在 apache-tomcat-8.5.38/conf/web.xml 文件中),這時所有項目的父配置文件
四、Cookie 和 session 的區別
- session 存儲數據在服務器端,Cookie 存儲在客戶端
- session 沒有數據大小限制,Cookie 有限制
- session 數據相對安全,Cookie 數據相對不安全