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

Meteor發表於2022-07-08

一、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過來的!
  • 尊重每一位學習知識的人,同時也尊重每一位分享知識的人。
  • ?你的點贊與關注,是我努力前行的無限動力。?

相關文章