Tomcat深入淺出——Session與Cookie(四)

一、Cookie

1.1 Cookie概念

Cookie:有時也用其複數形式 Cookies。類型為「小型文本文件」,是某些網站為了辨別用戶身份,進行Session跟蹤而儲存在用戶本地終端上的數據(通常經過加密),由用戶客戶端電腦暫時或永久保存的資訊

1.2 為什麼要使用Cookie

Cookie原理:當客戶端去訪問使用了cookie的伺服器時,伺服器會生成一份cookie發送到客戶端,客戶端會把這個數據保存起來,然後這樣下次使用時,伺服器就可以通過cookie知道是哪個客戶端了。

  • 首先我們要了解HTTP是無狀態的,所以我們需要使用cookie和session機制。Cookie翻譯為曲奇小餅乾,所以它非常的小,不超過4k。
  • 當我們在多個頁面都需要同一個數據時,我們的web程式無法將資訊記錄下來,所以導致了我們每次都需要從伺服器重新的去請求數據,這就導致了我們重複的干一個工作,所以就引出了cookie這個概念。

  • 可以了解到cookie只支援字元串形式

1.3 Cookie常用方法

  • cookie.setMaxAge(0);此方法用來設置cookie時間

    • 當值等於0時,意味著刪除cookie
    • 當值大於0時,意味著cookie的存活時間,會將瀏覽器數據存在本地的硬碟中。
    • 當值小於0時,表示存儲在瀏覽器的記憶體中,並不存儲到硬碟中,和沒調用一樣🤮
  • cookie1.setPath(req.getContextPath());設置訪問路徑

    -瀏覽器訪問這個路徑,一定要帶cookie才行

  • Cookie cookie1 = new Cookie("username",username);設置cookie對象存儲帳號

1.4 Cookie實現的應用

  • 我們可以通過設置cookie,將用戶的帳號密碼存儲在本地硬碟中,來設置10天內免登錄。但是cookie並不安全
  • 京東在未登錄的情況下,向購物車添加商品,然後關閉瀏覽器,再次打開瀏覽器時候,購物車的東西還在,將購物車的商品編號放到cookie當中,而cookie保存在硬碟文件當中。
  • 像我們瀏覽器中的記住密碼、或者訪問B站大學登陸一次以後下次就不用登錄了,這些都是利用了cookie機制

二、Session

2.1 Session原理

  • 在web伺服器中有一個session列表。類似於map集合。這個map集合的key存儲的是session ID。

  • 這個map集合的value存儲的是對應的session對象

  • 用戶發送第一次請求的時候:伺服器會創建一個新的session對象,同時給session對象生成一個id,然後web伺服器會將session的id發送給瀏覽器,瀏覽器將session的id保存在瀏覽器的快取中

  • 用戶發送第二次請求的時候:會自動將瀏覽器快取中的sessionID 自動發送給伺服器,伺服器獲取到session ID,然後從session列表中查找到對應的session對象

  • 因為session是存放於伺服器中的,這也是它和cookie的區別。

  • JSESSION=xxxxxx 這個是以Cookie的形式保存在瀏覽器的記憶體中的,瀏覽器只要關閉,這個cookie就沒有了

2.2你以為session真的銷毀了嗎?

1.為什麼我們每次關閉了瀏覽器,會話就結束了?

  • 關閉瀏覽器之後,瀏覽器中保存的sessionID消失,下次重新打開瀏覽器之後,瀏覽器快取中沒有這個sessionID,自然找不到伺服器中對應的session對象,session對象找不到等同於會話結束!!!
  • 但是我們可以不關閉瀏覽器,而是直接關閉伺服器,這樣你會發現雖然他們都用同樣的sessionId,但是仍然找不到伺服器中對應的session對象,這就要了解一下session的鈍化活化了。

2.session銷毀的方式

  • 手動銷毀,將調用這個方法session.invalidate()
  • 自動銷毀,session在我們的配置文件中其實默認是30分鐘,時間一到他就會自動銷毀。
  • 我們可以通過session.setMaxInactiveInterval()設置超時時間

3.session實現原理:

  1. JSESSION=xxxxxx 這個是以Cookie的形式保存在瀏覽器的記憶體中的,瀏覽器只要關閉,這個cookie就沒有了
  2. session列表是一個Map,map的key是session,map的value是session對象
  3. 用戶第一次請求:伺服器生成session對象,同時生成id,將id發給瀏覽器
  4. 用戶第二次請求:自動將瀏覽器記憶體中的id發送給伺服器,伺服器根據id查找到cookie對象
  5. 關閉瀏覽器,記憶體消失,cookie消失,會話等同於結束!

2.3 session常用方法與應用場景

  • HttpSession session = req.getSession();獲取session,session是存在於一次會話中,我們可以將經常用的小資訊,放入裡面,例如登錄的User資訊,我們可以通過session,在每個頁面都能拿到數據,而不必對伺服器進行多次的請求。
  • session.setAttribute("user",person);設置session域。
  • request請求域(HttpServletRequest)、session會話域(HttpSession)、application域(ServletContext)域的大小關係為:request < session < application
//設置session銷毀時間
<session-config>
    <session-timeout>30</session-timeout>
</session-config>
  • 我們可以通過session進行判斷用戶是否登錄,如果已經註銷了登錄,則通過判斷session是否存在,控制用戶是否能夠訪問某些介面。

三、Session的鈍化和活化

      我們知道session是將資訊存儲到伺服器里的,但是為什麼我們每次關閉瀏覽器再打開,卻拿不到存在瀏覽器里的數據呢,這就需要我們了解一下如何鈍化活化

鈍化:當伺服器正常關閉時,還存活著的session(在設置時間內沒有銷毀) 會隨著伺服器的關閉被以文件(「SESSIONS.ser」)的形式存儲在tomcat 的這個目錄下,這個過程叫做Session 的鈍化。

活化:當伺服器再次正常開啟時,伺服器會找到之前的「SESSIONS.ser」 文件,從中恢復之前保存起來的Session 對象,這個過程叫做Session的活化。

  • 實現session鈍化和活化,它的pojo類必須實現Serializable介面,同時也可以實現一個HttpSessionActivationListener監聽Session行為的介面。
public class Person implements Serializable, HttpSessionActivationListener {
    private static final long serialVersionUID = 1L;
    private String name;
    private Integer age;
    
    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {
      
        System.out.println("會話將被鈍化,數據保存到硬碟");
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        System.out.println("會話被活化,數據從硬碟中取出來了");
    }

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 我們分別設置兩個Servlet類,一個用來放session資訊,一個用來取session資訊
//用來存儲session資訊
@WebServlet("/sessionTest")
public class SessionTest extends HttpServlet{
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        Person person = new Person();
        person.setName("lx");
        person.setAge(20);
        session.setAttribute("user",person);
    }
}
//用來拿到session資訊
@WebServlet("/sessionTest01")
public class SessionTest01 extends HttpServlet{
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        Person user =(Person) session.getAttribute("user");
        System.out.println(user.getName());
        System.out.println(user.getAge());
    }
}

最後一步,配置文件:

  • 在我們的Tomcat目錄下的conf中的context.xml添加如下資訊

  • 下面讓我們來測試一下

四、cookie和session區別

五、結尾

  • 對於Tomcat的Servlet內容就總結這麼多,若想深入學習等待後續更新。
  • 我將會繼續更新關於Java方向的學習知識,感興趣的小夥伴可以關注一下。
  • 文章寫得比較走心,用了很長時間,絕對不是copy過來的!
  • 尊重每一位學習知識的人,同時也尊重每一位分享知識的人。
  • 😎你的點贊與關注,是我努力前行的無限動力。🤩
Tags: