簡述會話跟蹤技術——Cookie和Session

簡述會話跟蹤技術——Cookie和Session

本篇文章將會簡單介紹Cookie和Session的概念和用法

會話跟蹤技術

首先我們需要搞清楚會話和會話跟蹤的概念:

  • 會話:用戶打開瀏覽器,訪問Web伺服器的資源,會話建立,直到有一方斷開連接,會話結束;在一次會話中可以包含多次請求和響應
  • 會話跟蹤:一種維護瀏覽器狀態的方法,伺服器需要識別多次請求是否來自同一瀏覽器,以便在同一次會話的多次請求間共享數據

但是我們實際上是無法直接判斷請求是否來自同一瀏覽器:

  • HTTP協議是無狀態的,每次瀏覽器向伺服器請求時,伺服器都會將該請求視為新的請求
  • 因而我們需要會話跟蹤技術來實現會話內數據共享

會話跟蹤技術實現方式:

  • 客戶端會話跟蹤技術:Cookie
  • 服務端會話跟蹤技術:Session

Cookie是一種客戶端會話跟蹤技術

為什麼把Cookie稱為客戶端會話跟蹤技術呢:

  • Cookie的本質是一種簡單的客戶端存儲機制,負責存儲少量的文本數據
  • Cookie的實現基於HTTP協議,在客戶端和伺服器進行請求響應交互時,Cookie會將部分文本攜帶
  • 當客戶端向伺服器A發送請求時,伺服器的response響應中會攜帶Set-cookie響應頭並存儲相關用戶資訊
  • 當客戶端向伺服器B發送請求時,客戶端的request請求中會攜帶cookie請求頭存儲之前的相關用戶資訊用於判斷是否來自同一客戶端

Cookie基本使用

Cookie:客戶端會話技術,將數據保存到客戶端,以後每次請求都攜帶Cookie數據進行訪問

Cookie使用的相關程式碼:

  • 發送Cookie

創建Cookie對象,設置數據

Cookie cookie = new Cookie("key","value");

發送Cookie到客戶端,使用response對象

response.addCookie(cookie);
  • 獲取Cookie

獲得客戶端攜帶的所有Cookie對象,使用request對象

Cookie[] cookies = request.getCookies();

遍曆數組,得到每一個Cookie對象

for(Cookie c : cookies)
	{
	.......
}

使用Cookie對象方法獲得數據

// 獲得該cookie的Key
cookie.getName();

//獲得該cookie的Value
cookie.getValue();

Cookie使用細節

Cookie存活時間:

  • Cookie存活時間是指在瀏覽器中的存儲時間
  • 默認情況下,Cookie存儲在瀏覽器記憶體中,當瀏覽器關閉,記憶體釋放,則Cookie被銷毀

Cookie存活時間修改方法:

// 設置該cookie的存活時間
cookie.setMaxAge(int seconds);

/*
seconds可以選擇所有數值:
正數:可以保存該秒數;一般情況下以*來展示,例如60*60*24*7表示一周
0:表示立即銷毀
負數:表示默認情況,當瀏覽器關閉,記憶體釋放,cookie銷毀
*/

Cookie存儲中文:

  • 正常情況下Cookie是無法存儲中文的
  • 但我們可以通過轉碼(URL編碼)來解決這個問題

Cookie示例程式碼

我們將給出一個示例程式碼來展現上述介紹:

/*
客戶端
*/

package com.itheima.web.cookie;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;

@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //發送Cookie

        //1. 創建Cookie對象
		//   Cookie cookie = new Cookie("username","zs");

        String value = "張三";
        //URL編碼
        value = URLEncoder.encode(value, "UTF-8");

        Cookie cookie = new Cookie("username",value);

        //設置存活時間   ,1周 7天
        cookie.setMaxAge(60*60*24*7);

        //2. 發送Cookie,response
        response.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
/*
伺服器
*/


package com.itheima.web.cookie;

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 java.io.IOException;
import java.net.URLDecoder;

@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1. 獲取Cookie數組
        Cookie[] cookies = request.getCookies();

        //2. 遍曆數組
        for (Cookie cookie : cookies) {
            //3. 獲取數據
            String name = cookie.getName();
            if("username".equals(name)){
                String value = cookie.getValue();
                //URL解碼
                value = URLDecoder.decode(value,"UTF-8");

                System.out.println(name+":"+value);

                break;
            }
        }

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

Session

Session是一種伺服器會話跟蹤技術

為什麼把Session稱為伺服器會話跟蹤技術呢:

  • 首先Session實際上是基於Cookie實現的
  • Session是一種資源,自身帶有ID屬性,且每一個Session有單獨的ID
  • 當我們的Servlet通過request獲得Session後,返回給客戶端的response中會攜帶Session的ID碼,客戶端就會保存下這個ID
  • 客戶端在之後的伺服器交互中就會攜帶這個ID作為request的一部分,伺服器在接收request之後就可以判斷是否屬於一次會話
  • 上述的攜帶ID碼的流程均由Cookie的請求頭cookie和響應頭set-cookie攜帶,所以說Session實際上是基於Cookie實現的

Session基本使用

Session:服務端會話跟蹤技術,將數據保存到服務端,JavaEE提供HTTPSession介面,實現一次會話的多次請求間數據共享功能

Session使用的相關程式碼:

  • 獲得Session對象
HttpSession session = request.getSession();
  • Session對象功能
// 存儲資訊功能
void setAttrubute(String name,Object o)
    
// 根據Key,獲得Value
Object getAttrubute(String name)
    
// 根據Key,刪除鍵值對
void removeAttrbute(String name)

Session使用細節

Session的鈍化和活化:

  • 在伺服器重啟後,Session的數據仍舊保存!
  • 鈍化:在伺服器正常關閉後,Tomcat會自動將Session數據寫入硬碟的文件中
  • 活化:在再次啟動伺服器後,從文件中載入數據到Session中

Session的銷毀:

  • 可以調用Session對象的invalidate()方法主動銷毀
  • 默認情況下,無操作,在30min後自動銷毀
  • 自動銷毀時間可以自定義
<!-- 在Web.xml中定義 -->
    <session-config>
        <!--這裡的單位是min-->
        <session-timeout>100</session-timeout>
    </session-config>

Session示例程式碼

我們將給出一個示例程式碼來展現上述介紹:

package com.itheima.web.session;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/demo1")
public class SessionDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //存儲到Session中
        //1. 獲取Session對象
        HttpSession session = request.getSession();
        System.out.println(session);
        //2. 存儲數據
        session.setAttribute("username","zs");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
package com.itheima.web.session;

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;
import java.io.IOException;

@WebServlet("/demo2")
public class SessionDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取數據,從session中

        //1. 獲取Session對象
        HttpSession session = request.getSession();
        System.out.println(session);

        // 銷毀(注意:銷毀後,後續有關該Session程式碼無法進行)
        // session.invalidate();

        //2. 獲取數據
        Object username = session.getAttribute("username");
        System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

小結

最後我們對Cookie和Session做一次相關對比

相同點:

  • Cookie和Session都是用來完成一次會話中多次請求間的數據共享

不同點:

  • 存儲位置:Cookie存儲在客戶端;Session存儲在服務端
  • 安全性:Cookie不安全,Session安全
  • 數據大小:Cookie最大為3KB,Session大小無限制
  • 存儲時間:Cookie可長期存儲,Session默認30min
  • 伺服器性能:Cookie不佔用伺服器資源,Session佔用伺服器資源

結束語

好的,關於Cookie和Session的內容就到這裡,希望能為你帶來幫助

附錄

該文章屬於學習內容,具體參考B站黑馬程式設計師陳老師的JavaWeb課程

這裡附上鏈接:01-會話跟蹤技術概述_嗶哩嗶哩_bilibili

Tags: