Session

Josen_Earth發表於2024-08-19

Session執行機制

a.在伺服器建立Session物件,Session物件生成一個全球唯一的id

b.在伺服器建立Session物件的同時,還會建立Cookie物件,不過這個Cookie物件的名字有一個固定值JSESSIONID,該值等於Session生成的全球唯一id

c.以後每次瀏覽器訪問伺服器都會攜帶名字是JSESSIONID的Cookie物件

d.伺服器根據JSESSIONID對應的值,在伺服器中查詢是否有對應的Session物件,一次來區分不同的使用者

HttpSession session = request.getSession();  //生成session物件
 String id = session.getId();      //全球唯一Id

 

================================================================================================

【Session簡述】

* 在Web開發中,伺服器可以為每個使用者瀏覽器建立一個會話物件(session物件),注意:一個瀏覽器獨佔一個session物件(預設情況下),因此,在需要儲存使用者資料時,伺服器程式可以把使用者資料寫到使用者瀏覽器獨佔的session中,當使用者使用瀏覽器訪問其它程式時,其它程式可以從使用者的session中取出該使用者的資料,為使用者服務。

【session和cookie的主要區別】

* Cookie是把使用者的資料寫到使用者的瀏覽器。

* Session技術把使用者的資料寫到使用者獨佔的session中。

[ Cookie的侷限 ]

  1.Cookie只能存字串型別,不能儲存物件

  2.不能存中文,資料型別只能為非中文String。

  3.1個cookie的容量不能超過4KB。

  4.相對資料存放不安全

[ Session的特點 ]

  1.會話資料存放在伺服器端(伺服器記憶體),佔用的是伺服器資源。

  2.資料型別是任意的,沒有大小的限制。

  3.相對安全。

 

【獲取session】

Session物件由伺服器建立,開發人員可以呼叫request物件的getSession方法得到session物件。

 

【Session 使用核心技術】

HttpSession類:用於儲存會話資料。

1.建立或得到HttpSession物件

  HttpSession request.getSession()

  HttpSession request.getSession(boolean create)

2.設定session物件

  void setMaxInactiveInterval(int interval) :設定session的有效時間(單位:秒)

  void invalidate():手動銷燬session物件

  String getId():得到session的編號Id

3.儲存會話資料得到Session物件

  void setAttribute(String name,Object value):儲存資料

  Object getAttribute( String name ):獲取資料

  void  removeAttribute(String name):清除資料

 

【Session原理】

1.伺服器建立Session物件,分配一個唯一的標記(JSESSIONID),會話資料儲存在Session物件中,然後伺服器把JSESSIONID作為Cookie傳送給瀏覽器儲存。

  響應頭:JSESSIONID=7EBC5D0B44D9D3DDE7FAD83C077E3D3E

2.瀏覽器得到JSESSIONID的cookie,儲存在瀏覽器的目錄中

3.瀏覽器在下次訪問伺服器的時候,帶著JSESSION的cookie資料訪問伺服器。

  請求頭:Cookie:JSESSIONID=7EBC5D0B44D9D3DDE7FAD83C077E3D3E

4.伺服器得到JSESSIONID,在伺服器記憶體中查詢是否存在對應的編號的Session物件。

5.如果找到對應的Session物件,返回這個物件

6.如果找不到對應的Session物件,有可能返回null,也有可能是建立新的session物件(HttpSession session=request.getSession(); )

[核心的幾個方法] 

  HttpSession session=request.getSession();

1.建立Session物件

  Session session=new Session();

  Cookie cookie=new Cookie("JESSIONID","001");  //注意預設儲存在瀏覽器內

  response.addCookie(cookie);

2.得到Session物件

  在伺服器查詢對應的JESSIONID的物件,返回session物件。

結論:瀏覽器通過JESSIONID(Session編號)在伺服器中查詢session物件

 

【session的幾個細節】

 1.setMaxInactiveInterval:設定Session物件的有效時間

  注意:並不是瀏覽器關閉,session就銷燬!!

  預設情況:等待30分鐘空閒時間,session物件才會銷燬。

設定全域性的Session物件的過期時間(分鐘),如下:

<!--  設定全域性的Session物件的過期時間(分鐘) -->
<session-config>
    <session-timeout> 1 </session-timeout>
</session-config>

2.可以讓JSESSIONID不會隨著瀏覽器關閉而丟失!!

/**
* 設定JESSIONID的時間,不會隨著瀏覽器的關閉而丟失!
*/
Cookie c=new Cookie("JESSIONID",session.getId());
c.setMaxAge(1*30*24*60*60);   //1個月
response.addCookie(c);

3.直接手動銷燬Session物件

invalidate();

4.建立或得到Session物件

request.getSession(); / request.getSession(true);     //建立或得到session物件,查詢session物件,如果沒有對應的session物件,就建立新的session物件。
request.getSession(false);  //得到Session物件。查詢session物件,如果沒有直接返回null

 

【Session入門案例】

[SessionDemo00.java]  儲存一個Session物件

 

package com.session.servlet;

import java.io.IOException;

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;

@WebServlet("/SessionDemo00")
public class SessionDemo00 extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    public SessionDemo00() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        HttpSession session=request.getSession();
        session.setAttribute("name", "哈哈哈哈");
        
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

}

 

[SessionDemo01.java] 查詢對應的Session物件

package com.session.servlet;

import java.io.IOException;
import java.io.PrintWriter;

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;

@WebServlet("/SessionDemo01")
public class SessionDemo01 extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    public SessionDemo01() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out=response.getWriter();
        
        HttpSession session=request.getSession();
        String value=(String) session.getAttribute("name");
        //輸出獲取的Session資料到瀏覽器
        out.write("獲得Session值是:"+value);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

}

 

【執行結果】

[ 1.第一次訪問SessionDemo00 ]

 

[ 2.然後訪問SessionDemo01 ]

 [ 隱藏問題:關閉對應的火狐瀏覽器,重新訪問SessionDemo01,會出現以下情況 ]

【如何解決上面的而隱藏問題,我們希望所有瀏覽器所有頁面後,訪問ServletDemo01時仍能獲取對應的Session】

[ ServletDemo00.java ] 需要在ServletDemo00中程式碼修改

 

package com.session.servlet;

import java.io.IOException;

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 javax.servlet.http.HttpSession;

@WebServlet("/SessionDemo00")
public class SessionDemo00 extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    public SessionDemo00() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        HttpSession session=request.getSession();
    /*-------------------增加以下程式碼--------------------------*/
        String sessionId=session.getId();
        Cookie cookie=new Cookie("JSESSIONID",sessionId);
        cookie.setPath("/HelloServlet");
        cookie.setMaxAge(10*60);  //有效期10分鐘
        response.addCookie(cookie);
        
        session.setAttribute("name", "哈哈哈哈");
        
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

}

[ 關閉瀏覽器所有頁面後(首先訪問過SessionDemo00),再次訪問SessionDemo01後 ]

相關文章