iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
Software Development

從Servlet到Spring MVC系列 第 15

Day14 Servlet - Cookie and Session

  • 分享至 

  • xImage
  •  

前言

老王是王牌麵館的老主顧,每次去都只會點滷肉飯、燙青菜跟豆乾海帶一盤,當他去店裡跟老闆說點跟上次一樣的餐點,但老闆始終不記得。於是聰明的老闆想到給老王一張貴賓卡上面記載老王的會員編號,老王的用餐習慣就記載他的電腦裡,只要老王下次來刷一下貴賓卡就可以直接點餐,是不是很方便呢

因為Http是無狀態的記不住客戶喜好,只好透過把貴賓卡(Cookie)放在老王的身上,把客戶喜好存在電腦(Sesson)裡。

0、創建module

請參考Day05創建module

一、Cookie

Cookie是由Web Server產生放在瀏覽器的一小份資訊,第一次創建後的每次訪問該Web Server都會被攜帶過去。

  • Cookie是一種key value的數據格式。
  • Cookie是存在客戶端的數據容易暴露,故不會存敏感資訊。

(1) Cookie使用

放置cookie

@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //創建Cookie
        Cookie cookie1 = new Cookie("k1", "value1");
        Cookie cookie2 = new Cookie("k2", "value2");

        resp.addCookie(cookie1);
        resp.addCookie(cookie2);


    }
}

取得cookie

@WebServlet("/GetCookieServlet")
public class GetCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName() + " : " + cookie.getValue());
            }
        }
        
    }
}

先訪問
https://ithelp.ithome.com.tw/upload/images/20240929/201280842Oa58l61lK.png
再訪問
https://ithelp.ithome.com.tw/upload/images/20240929/20128084vsiTSAh5eA.png

(2) Cookie時效性

cookie默認是一次會話範圍內,可以透過Cookie的SetMaxAge()方法讓Cookie保留在瀏覽器中。
設置維持久化cookie

@WebServlet("/CookieSetMaxServlet")
public class CookieSetMaxServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse res){
        Cookie cookie = new Cookie("CookieSetMax", "CookieSetMaxValue");
        //api second
        cookie.setMaxAge(60*5);
        res.addCookie(cookie);
    }
}

重啟tomcat,先訪問/CookieSetMaxServlet
https://ithelp.ithome.com.tw/upload/images/20240929/20128084eiDyVUbSKS.png
再訪問/CookieServlet
https://ithelp.ithome.com.tw/upload/images/20240929/20128084YzctGsAm74.png
再訪問/GetCookieServlet
https://ithelp.ithome.com.tw/upload/images/20240929/20128084FnsRlB2vof.png
關掉瀏覽器再重開瀏覽器訪問/GetCookieServlet,只剩CookieSetMax
https://ithelp.ithome.com.tw/upload/images/20240929/20128084ASOJ7RnI6v.png

(3) Cookie提交路徑

也可以針對訪問路徑才攜帶Cookie

@WebServlet("/SetPathCookieServlet")
public class SetPathCookieServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse res){
        Cookie cookie = new Cookie("SetPathCookie", "SetPathCookieValue");
        cookie.setPath("/CookieServlet");
        res.addCookie(cookie);
    }
}

先訪問/SetPathCookieServlet
https://ithelp.ithome.com.tw/upload/images/20240929/20128084ZcQubQRxM3.png
再訪問/CookieSetMaxServlet,未帶SetPathCookie
https://ithelp.ithome.com.tw/upload/images/20240929/20128084MAs6sP7Xx8.png
最後訪問/CookieServlet
https://ithelp.ithome.com.tw/upload/images/20240929/20128084NXBr6zUwVG.png

二、Session

Web Server會為每個客戶開一塊空間即Session Object透過JESSIONID,Server就可以紀錄與查找客戶的狀態了。

  • Server端創建Session時,會將Session id以JESSIONID以Cookie的形式放置在response物件中
  • 客戶下次請求就會帶上該cookie,Server再根據id查找客戶訊息

(1) 應用場景

  • 紀錄客戶登錄狀態
  • 紀錄客戶操作歷史,例如購物車

(2) HttpSession使用

創建SessionServlet

@WebServlet("/SessionServlet")
public class SessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        System.out.println("=====GetSessopnDataServlet=====");
        String username = req.getParameter("username");

        HttpSession session = req.getSession();
        System.out.println(session.isNew());
        System.out.println(session.getId());
        session.setAttribute("username", username);
    }
}

創建GetSessopnDataServlet

@WebServlet("/GetSessopnDataServlet")
public class GetSessopnDataServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        System.out.println("=====GetSessopnDataServlet=====");
        HttpSession session = req.getSession();
        System.out.println(session.isNew());
        System.out.println(session.getId());
        System.out.println("data:"+session.getAttribute("username"));

    }
}

先訪問SessionServlet
https://ithelp.ithome.com.tw/upload/images/20240929/20128084k0djT1Yae2.png
再訪問http://localhost:8080/GetSessopnDataServlet?username=james
https://ithelp.ithome.com.tw/upload/images/20240929/20128084VVsTAYI9qQ.png

(3) HttpSession時效

  • 當客戶數量多相對應的session的物件也會被創建很多,如果都沒釋放資源肯定會耗盡
  • default的session時效性為30分鐘
  • 可以透過web.xml進行設定
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <session-config>
    <session-timeout>10</session-timeout>
  </session-config>
</web-app>
@WebServlet("/SessionSetMaxServlet")
public class SessionSetMaxServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse res){
        System.out.println("=====SessionSetMaxServlet=====");
        HttpSession session = req.getSession();
        session.setMaxInactiveInterval(300);

        //let session fail
        //session.invalidate();
    }
}

在tomcat資料夾下conf/web.xml中可以查到預設時間,當你設置在專案內WEB-INFO下會以此優先
https://ithelp.ithome.com.tw/upload/images/20240929/20128084JxeDOfpHbm.png

Reference


上一篇
Day13 Servlet - Absolute and relative path
下一篇
Day15 Servlet - Scope Object
系列文
從Servlet到Spring MVC36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言