HTTP 會話技術 (Cookie、Session )

目錄

一、概念

二、Cookie 客戶端會話技術

1、Cookie 使用步驟

2、實現原理

3、Cookie 特點

4、Cookie 共享問題

三、Session 服務器端會話技術

1、獲取 HTTPSession 對象

2、session 特點

3、Session 會話原理

4、Session 共享問題

5、session 銷燬時間

四、Cookie 和 session 的區別


一、概念

會話技術就是客戶端和服務器之間的通信,一次會話包含多次請求和響應,從客戶端第一次給服務器發送請求開始建立會話到有一方斷開爲止。

  • 功能:在一次會話的範圍內能有多次請求響應,可以實現多次請求響應之間的數據共享
  • 會話方式
    • 客戶端會話技術:Cookie(將數據保存在客戶端)
    • 服務器會話技術:Session(將數據保存在服務器)

二、Cookie 客戶端會話技術

Cookie 客戶端會話技術既是在瀏覽器客戶端向服務器發送請求,請求完成後,服務器會攜帶一些數據相應給瀏覽器客戶端,瀏覽器客戶端會將數據保存在本地;下一次請求會攜帶者數據請求

1、Cookie 使用步驟

  1. 服務器創建 Cookie 對象:new Cookie(String name,String value)
  2. 客戶端發送 Cookie 對象:response.addCookie(Cookie cookie)
  3. 服務器獲取 Cookie 對象:Cookie[] response.getCookies()

2、實現原理

  1. 客戶端發送請求給服務器
  2. 服務器發送響應頭set-cookie並攜帶數據給客戶端
  3. 客戶端將響應頭攜帶的數據保存到客戶端瀏覽器中
  4. 下一次請求服務器會使用消息頭cookie數據攜帶給服務器
  5. 服務器獲取消息頭中的數據

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")
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 對象是同一個

  1. 瀏覽器向服務器發送請求
  2. 服務器響應瀏覽器並攜帶唯一標識(使用響應頭攜帶set-cookie)
  3. 瀏覽器再次發送請求將唯一標識攜帶給服務器(使用cookie)
  4. 服務器判斷瀏覽器是否攜帶唯一標識
    • 若攜帶唯一標識:
      • 服務器拿着唯一標識去 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);

【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 銷燬時間

  1. ​​​​​​​服務器關閉
  2. session 對象調用 invalidata() 方法
  3. session 默認失效時間:30分鐘
    • 可以修改配置文件來修改默認失效時間(在 apache-tomcat-8.5.38/conf/web.xml 文件中),這時所有項目的父配置文件
      ​​​​​​​<session-config>
          <session-timeout>30</session-timeout>
      </session-config>
       

四、Cookie 和 session 的區別

  • session 存儲數據在服務器端,Cookie 存儲在客戶端
  • session 沒有數據大小限制,Cookie 有限制
  • session 數據相對安全,Cookie 數據相對不安全
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章