Java學習筆記(七十二)—— Cookie

miles-zh發表於2020-02-12
概述

會話技術

  • 會話:一次會話中包含多次請求和響應
    • 一次會話:瀏覽器第一次給伺服器傳送資源請求,會話建立,直到有一方斷開為止
  • 功能:在一次會話的範圍內的多次請求間,共享資料
  • 方式:
    • 客戶端會話技術:Cookie,把資料儲存到客戶端
    • 伺服器端會話技術:Session,把資料儲存到伺服器端
Cookie

概念:客戶端會話技術,將資料儲存到客戶端
快速入門

  • 使用步驟:
  1. 建立Cookie物件,繫結資料 new Cookie(String name,String value)

  2. 傳送Cookie物件 response.addCookie(Cookie cookie)

  3. 獲取Cookie,拿到資料 Cookie[] request.getCookies()

    @WebServlet("/CookieDemo1")
    public class CookieDemo1 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            Cookie cookie = new Cookie("msg", "hello");
            response.addCookie(cookie);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request,response);
        }
    }
    @WebServlet("/CookieDemo2")
    public class CookieDemo2 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            Cookie[] cookies = request.getCookies();
            if(cookies!=null){
                for (Cookie cookie : cookies) {
                    System.out.println(cookie.getName());
                    System.out.println(cookie.getValue());
                }
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request,response);
        }
    }

實現原理

  • 基於響應頭set-cookie和請求頭cookie實現

Cookie細節

  • 一次可不可以傳送多個cookie?
    • 可以建立多個cookie物件,使用response呼叫多次addCookie方法傳送cookie即可
  • cookie在瀏覽器中儲存多久?
    • 預設情況下,當瀏覽器關閉後,cookie資料被銷燬
    • 持久化儲存:setMaxAage(int seconds)
      • 取值整數:將Cookie資料寫道硬碟的檔案中,持久化儲存。cookie的存活時間。
      • 取值負數:預設值
      • 取值零:刪除cookie資訊
    		Cookie cookie = new Cookie("msg", "hello");
            // 設定cookie的存活時間,30s後自動刪除
            cookie.setMaxAge(30);
  • cookie能不能存中文?
    • 在tomcat 8 之前不能儲存中文,之後可以儲存中文,但是不支援特殊字元,建議使用URL編碼儲存,使用URL解碼解析
  • cookie獲取的範圍多大?
    • 如果在tomcat伺服器中部署了多個web專案,那麼在這些web專案中cookie能不能共享。
      • 預設情況下不能共享
      • setPath(String path),設定cookie的取值範圍,
        • 預設情況下是設定的是當前的虛擬目錄
        • 如果要共享。則可以將path設定為“/”
    • 不同的tomcat伺服器間cookie共享問題
      • 呼叫cookie的方法setDomain(String path):如果設定一級域名相同,那麼多個伺服器之間cookie可以共
    Cookie cookie = new Cookie("msg", "hello");
    // 那麼tieba.baidu.com和news.baidu.com中cookie可以共享
    cookie.setDomain(".baidu.com")

Cookie特點和作用

  • cookie儲存資料在客戶端瀏覽器
  • 瀏覽器對單個cookie的大小有限制(4kb),對同一個域名下的總cookie數量(20個)有限制按照
  • 作用:
    • cookie一般用於儲存少量的不太敏感的資料
    • 在不登入的情況下,完成伺服器對客戶端的身份識別

案例

  • 記住上一次訪問時間
@WebServlet("/CookieTest")
public class CookieTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        // 獲取所有的cookie
        Cookie[] cookies = request.getCookies();
        boolean flag=false;
        // 遍歷cookie
        if(cookies!=null&&cookies.length>0){
            
            for (Cookie cookie : cookies) {
                // 獲取cookie的名稱

                String name = cookie.getName();
                System.out.println(name);
                // 判斷cookie的名稱是否是lastTime
                if("lastTime".equals(name)){
                    flag=true;
                    // 設定cooki的value
                    Date date=new Date();
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String strDate = sdf.format(date);
                    // URL編碼
                    String encode = URLEncoder.encode(strDate, "utf-8");
                    cookie.setValue(encode);
                    cookie.setMaxAge(60*60*24*30);
                    response.addCookie(cookie);
                    // 響應資料
                    String value = cookie.getValue();
                    // URL 解碼
                    String decode = URLDecoder.decode(value, "utf-8");
                    response.getWriter().write("歡迎回來!您上一次的訪問時間為"+decode);
                    break;
                }
                
            }
        }
        
        if(cookies==null||cookies.length==0||flag==false){
            Date date=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String strDate = sdf.format(date);
            // URL編碼
            String encode = URLEncoder.encode(strDate, "utf-8");
            Cookie cookie = new Cookie("lastTime",encode);
            cookie.setMaxAge(60*60*24*30);
            response.addCookie(cookie);
            response.getWriter().write("歡迎您首次訪問!");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

相關文章