1. 程式人生 > 實用技巧 >【JavaWeb】Cookie&Session

【JavaWeb】Cookie&Session

Cookie&Session

  • Cookie 即餅乾的意思
  • Cookie 是伺服器通知客戶端儲存鍵值對的一種技術
  • 客戶端有了 Cookie 後,每次請求都發送給伺服器
  • 每個 Cookie 的大小不能超過 4kb
  • 客戶端(瀏覽器):
    • 如果沒有 Cookie,則通知伺服器
    • 收到響應後,發現有 響應頭 Set-Cookie,就去看一下,有沒有這個 Cookie,無則建立,有則修改
  • 伺服器(Tomcat):
    • 建立 Cookie 物件
    • 通知客戶端儲存 Cookie
    • 通過 響應頭 Set-Cookie(Set-Cookie: key1=value1)通知客戶端儲存 Cookie
// 建立 Cookie
protected void createCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1. 建立 Cookie 物件
    Cookie cookie = new Cookie("key1", "value1");
    // 2. 通知客戶端儲存 Cookie
    response.addCookie(cookie);
    // 1. 建立 Cookie 物件
    Cookie cookie2 = new Cookie("key2", "value2");
    // 2. 通知客戶端儲存 Cookie
    response.addCookie(cookie2);
    response.getWriter().write("Cookie 建立成功");
}
  • 客戶端(瀏覽器):
    • 如果有了 Cookie,通過 請求頭 Cookie: xx=xx 把 Cookie 資訊傳送給伺服器
  • 伺服器(Tomcat):獲取客戶端傳送過來的 Cookie
 // 獲取 Cookie
protected void getCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 獲取客戶端傳送過來的 Cookie
    Cookie[] cookies = request.getCookies();
    response.getWriter().write("Cookie 獲取成功");

    for (Cookie cookie : cookies) {
        response.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "] <br/>");
    }

    Cookie iWantCookie = CookieUtils.findCookie("key1", cookies);
    if (iWantCookie != null) {
        response.getWriter().write("找到了需要的 key1 Cookie: " + iWantCookie.getValue());
    }
}
 // 修改 Cookie
    protected void updateCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 方案一:
        //1、先建立一個要修改的同名(指的就是 key)的 Cookie 物件
        //2、在構造器,同時賦於新的 Cookie 值
        Cookie newCookie = new Cookie("key1", "new-value1");
        //3、呼叫 response.addCookie( Cookie ) 通知客戶端儲存修改
        response.addCookie(newCookie);

        // 方案二:
        //1、先查詢到需要修改的 Cookie 物件
        Cookie newCookie2 = CookieUtils.findCookie("key2", request.getCookies());
        //2、呼叫 setValue()方法賦於新的 Cookie 值
        if (newCookie2 != null) {
            newCookie2.setValue("new-value2");
        }
        //3、呼叫 response.addCookie( Cookie ) 通知客戶端儲存修改
        response.addCookie(newCookie2);

        response.getWriter().write("Cookie 修改成功");
    }

Cookie 的生命控制指的是如何管理 Cookie 什麼時候被銷燬(刪除)。

setMaxAge(maxAge):

  • 正數,表示在指定的秒數後過期
  • 負數,表示瀏覽器一關,Cookie 就會被刪除(預設值是-1),這是預設值
  • 零,表示馬上刪除 Cookie

// Cookie 存活 120s。
protected void life120Cookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie cookie = new Cookie("life120Cookie", "life120Cookie");
    cookie.setMaxAge(60 * 2);
    response.addCookie(cookie);
    response.getWriter().write("已經建立了一個存活二分鐘的 life120Cookie");
}

// Cookie 存活 0s,即刪除。
protected void deleteCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie cookie = CookieUtils.findCookie("defaultCookie", request.getCookies()) ;
    if (cookie != null) {
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        response.getWriter().write("defaultCookie 已經被刪除了");
    }

}

// Cookie 預設的會話級別 session。
protected void defaultCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie cookie = new Cookie("defaultCookie", "defaultCookie");
    cookie.setMaxAge(-1);
    response.addCookie(cookie);
    response.getWriter().write("已經建立了一個預設的 defaultCookie");
}

Cookie 的 path 屬性可以有效的過濾哪些 Cookie 可以傳送給伺服器,哪些不發。path 屬性是通過請求的地址來進行有效的過濾。

 // 路徑設定
protected void setPath(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie cookie = new Cookie("path1", "path1");
    cookie.setPath(request.getContextPath() + "AA");    // 得到工程路徑
    response.addCookie(cookie);
    response.getWriter().write("建立了一個帶有 Path 路徑的 Cookie");
}

免輸入使用者名稱登入

<%--
  Created by IntelliJ IDEA.
  User: parzulpan
  Date: 2020/12/12
  Time: 5:47 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>免輸入使用者名稱登入</title>
</head>
<body>

    <form action="cookieServlet" method="get">
        <input type="hidden" name="action" value="loginWithCookie"/>
        使用者名稱:<input type="text" name="username" value="${cookie.username.value}"> <br>
        密碼:<input type="password" name="password"> <br>
        <input type="submit" value="登入">
    </form>

</body>
</html>
 // 免輸入使用者名稱登入
protected void loginWithCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    if ("parzulpan".equals(username) && "123456".equals(password)) {
        // 登入成功
        Cookie cookie = new Cookie("username", username);
        cookie.setMaxAge(60 * 60 * 24 * 7); // 當前 Cookie 一週內有效
        response.addCookie(cookie);
        System.out.println("登入成功");
    } else {
        System.out.println("登入失敗");
    }
}

Session

什麼是 Session 會話

  • Session 就是一個介面(HttpSession)
  • Session 就是會話,它是用來維護一個客戶端和伺服器之間關聯的一種技術
  • 每個客戶端都有自己的一個 Session 會話
  • Session 會話中,經常用來儲存使用者登入之後的資訊

建立和獲取 Session

  • request.getSession() 第一次呼叫是建立 Session 會話,之後呼叫都是獲取前面建立好的 Session 會話物件
  • isNew() 判斷是不是新的 Session,true 表示剛建立,false 表示獲取之前建立
  • getId() 得到 Session 的會話 ID 值,每個會話都有一個唯一的 ID 值
// 建立和獲取 Session
protected void createOrGetSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session = request.getSession();
    boolean isNew = session.isNew();
    String id = session.getId();

    response.getWriter().write("得到的 Session 的 Id 是:" + id + "<br>");
    response.getWriter().write("這個 Session 是否是新建立的:" + isNew + "<br>");
}

// 向 Session 中儲存資料
protected void setAttribute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getSession().setAttribute("key1", "value1");
    response.getWriter().write("已經往 Session 中儲存了資料");
}

// 獲取 Session 域中的資料
protected void getAttribute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Object key1 = request.getSession().getAttribute("key1");
    response.getWriter().write("從 Session 中獲取出 key1 的資料是:" + key1);
}

Session 生命週期

  • public void setMaxInactiveInterval(int interval) 設定 Session 的超時時間(以秒為單位),超過指定的時長 Session 就會被銷燬。值為正數的時候,設定 Session 的超時時長。負數表示永不超時(極少使用
  • public int getMaxInactiveInterval() 獲取當前 Session 的超時時間
  • public void invalidate() 讓當前 Session 會話馬上超時無效

Session 預設的超時時間長為 30 分鐘。因為在 Tomcat 伺服器的配置檔案 web.xml中預設有以下的配置,它就表示配置了當前 Tomcat 伺服器下所有的 Session 超時配置預設時長為:30 分鐘。

Session 超時指的是客戶端兩次請求的最大時間間隔時長

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

如果說希望你的 web 工程,預設的 Session 的超時時長為其他時長,可以在你自己的 web.xml 配置檔案中做以上相同的配置。

<!--表示當前 web 工程。創建出來 的所有 Session 預設是 20 分鐘 超時時長-->
<session-config>
    <session-timeout>30</session-timeout>
</session-config>
// Session 預設超時,預設超時時長為 30 分鐘,可以通過 Tomcat 的 web.xml 配置更改
protected void defaultSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    int maxInactiveInterval = request.getSession().getMaxInactiveInterval();
    response.getWriter().write("Session 預設超時時長:" + maxInactiveInterval);
}

// Session 10s 後超時
protected void life10Session(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session = request.getSession();
    session.setMaxInactiveInterval(10);
    response.getWriter().write("當前 Session 已經設定為 10 秒後超時");
}

// Session 馬上超時
protected void deleteSession(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 先獲取 Session 物件
    HttpSession session = request.getSession();
    // 讓 Session 會話馬上超時
    session.invalidate();
    response.getWriter().write("Session 已經設定為超時(無效)");
}

瀏覽器和 Session

Session 技術,底層其實是基於 Cookie 技術來實現的