• JavaWeb 之 Cookie


    Cookie 

    一、会话概述

      1、会话:一次会话中包含多次请求和响应。

            一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止。

    Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该信息处理请求。

      2、功能

        在一次会话的范围内的多次请求间,共享数据

      3、方式

        客户端会话技术:Cookie

        服务器端会话技术:Session

    二、Cookie 概述

      1、Cookie 是客户端会话技术,将数据保存到客户端,是服务器通知客户端保存键值对的一种技术;

      2、客户端有了 Cookie 后,每次请求都发送给服务器;

      3、每个 Cookie 的大小不能超过 4KB;

    三、Cookie 的使用

      1、创建 Cookie 对象

        Cookie 的 JDK 已经内置好的一个对象,可以通过构造方法直接来创建 cookie 对象;

        构造方法:

    Cookie cookie = new Cookie(String name,String value);
    

          创建一个 Cookie 对象,name 表示 cookie 的值,value表示 cookie 里面存放的值。

         使用 response 对象可以将 cookie 发送到客户端

        发送方法:

    response.addCookie(Cookie cookie) 

        原理图:

        

         代码示例:

     1 protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     2         //1 创建 Cookie 对象
     3         Cookie cookie = new Cookie("key1", "value1");
     4         //2 通知客户端保存 Cookie
     5         resp.addCookie(cookie);
     6         //1 创建 Cookie 对象
     7         Cookie cookie1 = new Cookie("key2", "value2");
     8         //2 通知客户端保存 Cookie
     9         resp.addCookie(cookie1);
    10         resp.getWriter().write("Cookie 创建成功");
    11     }

        注意

          ① 可以同时创建多个 cookie 对象,但是一定要用 addCookie() 方法设置到响应里;

          ② cookie() 不能包含中文和特殊字符,值不应包含空格、方括号、圆括号、等号、逗号、双引号、斜杠、问号、at 符号、冒号和分号。空值在所有浏览器上的行为不一定相同。

      2、服务器获取 Cookie

        在服务器获取客户端的 Cookie,需要使用 HttpServletRequest 的方法:

    Cookie[] request.getCookies():获取客户端所有的 cookie 对象
    String getName() 获取某个 cookie的 key(名)
    String getValue() 获取某个 cookie的 value(值)

          原理图:

        

        代码示例:

         把根据名称查找 Cookie 抽取成工具类:

     1  public class CookieUtils {
     2         /**
     3          * 查找指定名称的 Cookie 对象
     4          * @param name
     5          * @param cookies
     6          * @return
     7          */
     8         public static Cookie findCookie(String name , Cookie[] cookies){
     9             if (name == null || cookies == null || cookies.length == 0) {
    10                 return null;
    11             } 
    12             for (Cookie cookie : cookies) {
    13                 if (name.equals(cookie.getName())) {
    14                     return cookie;}
    15             } 
    16             return null;
    17         }
    18     }

         获取 Cookie: 

     1 protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     2         Cookie[] cookies = req.getCookies();
     3         for (Cookie cookie : cookies) {
     4         // getName 方法返回 Cookie 的 key(名)
     5         // getValue 方法返回 Cookie 的 value 值
     6             resp.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "] <br/>");
     7         } 
     8         Cookie iWantCookie = CookieUtils.findCookie("key1", cookies);
     9 
    10         // 如果不等于 null, 说明赋过值, 也就是找到了需要的 Cookie
    11         if (iWantCookie != null) {
    12             resp.getWriter().write("找到了需要的 Cookie");
    13         }
    14     }

      3、Cookie 值的修改

        方案一:

          ① 先创建一个要修改的同名(key)的 Cookie 对象;

          ② 在构造器中,同时赋于新的 Cookie 的值;

          ③ 调用 response.addCookie(Cookie);

        代码示例:

    1         // 1、 先创建一个要修改的同名的 Cookie 对象
    2         // 2、 在构造器, 同时赋于新的 Cookie 值。
    3         Cookie cookie = new Cookie("key1","newValue1");
    4         // 3、 调用 response.addCookie( Cookie ); 通知 客户端 保存修改
    5         resp.addCookie(cookie);

        方案二:

          ① 先查找到需要修改的 Cookie 对象;

          ② 调用 setValue() 方法赋于新的 Cookie 值;

          ③ 调用 response.addCookie() 通知客户端保存修改;

        代码示例:

    1    // 1、 先查找到需要修改的 Cookie 对象
    2     Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
    3     if (cookie != null) {
    4         // 2、 调用 setValue()方法赋于新的 Cookie 值。
    5         cookie.setValue("newValue2");
    6         // 3、 调用 response.addCookie()通知客户端保存修改
    7         resp.addCookie(cookie);
    8     }

    三、使用浏览器查看 Cookie

      1、谷歌浏览器查看 Cookie

        

      2、火狐浏览器查看 Cookie

        

    四、实现原理

      Cookie 基于响应头 set-cookie 和请求头 cookie 实现的。

      原理示意图:

      

       第一次访问服务器时,服务器就会给浏览器一个 “身份识别卡”,浏览器每次向服务器发送请求时都会带着这个 “身份识别卡”,当服务器看到这个 卡片时就可以识别浏览器的身份。

       实际上这个 “身份识别卡” 就是服务器发送的一个响应头:

       

       如上图 Set-Cookie 这个响应头就是服务器在向浏览器发送的 “身份识别卡”,这个响应头名字是 Set-Cookie,后面的 JSESSIONID=95A92EC1D7CCB4ADFC24584CB316382E 和 Path=/Test_cookie,是两组键值对的结构就是服务器为这个“身份识别卡”设置的信息。浏览器收到该信息后就会将它保存到内存或硬盘中。

       当浏览器再次向服务器发送请求时就会携带这个 Cookie 信息:

       

        这是浏览器发送的请求报文,中间画红框的就是 Cookie 信息,即浏览器带着“身份识别卡”访问服务器,服务器就可以根据 Cookie 信息来判断浏览器的状态。

    五、Cookie 生命控制(有效性)

       Cookie 是存储在浏览器中的,但是一般情况下浏览器不可能永久保存一个 Cookie,一是占用硬盘空间,二是 Cookie 可能只在某一时刻有用没必要长久保存。

       Cookie 的生命控制指的是如何管理 Cookie 什么时候被销毁(删除)

       可以通过下面的方法来进行设置:

    setMaxAge()设置 Cookie 的最大生存时间以秒为单位
        正数:表示在指定的秒数后过期
        负数:意味了 cookie 不会被持久存储,表示浏览器一关,Cookie 就会被删除
        零:Cookie 立即失效,表示马上删除 Cookie,下次浏览器发送请求将不会携带该 Cookie
       不设置:默认值是 -1,则默认当前会话有效,关闭浏览器失效。(会话级别)

      

    六、Cookie 有效路径 Path的设置

      Cookie 的 Path 属性可以有效的过滤哪些 Cookie 可以发送给服务器,哪些不发送。

      通过Cookie的 setPath() 来设置路径,这个路径是由浏览器来解析的所以/代表服务器的根目录,如果不设置,默认在访问 “/项目名” 下的资源时携带。

      path 属性是通过请求的地址来进行有效的过滤。

      图解:

      

      Demo:

    1 protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    2         Cookie cookie = new Cookie("path1", "path1");
    3         // getContextPath() ===>>>> 得到工程路径
    4         cookie.setPath( req.getContextPath() + "/abc" ); // ===>>>> /工程路径/abc
    5         resp.addCookie(cookie);
    6         resp.getWriter().write("创建了一个带有 Path 路径的 Cookie");
    7     }

    五、Cookie 细节

      1、一次可不可以发送多个 cookie?

         可以一次发送多个cookie对象。

         可以创建多个 cookie 对象,使用 response 调用多次 addCookie 方法发送 cookie 即可。

      2、cookie 在浏览器中保存多长时间?

        (1)默认情况下,当浏览器关闭后,cookie 数据被销毁

        (2)持久化存储

    setMaxAge(int seconds)  // 单位为秒
    

           ① 正数:将 cookie 数据写到硬盘的文件中。持久化存储,并指定 cookie 存活时间,时间到了,cookie 文件自动失效;

            ② 负数:默认值,关闭浏览器 cookie 销毁;

            ③ :删除当前的 cookie 信息;

      3、cookie 是否能够存储中文

        (1)在 Tomcat 8 之前,cookie 中不能直接存储中文数据。

           如果需要将中文数据转码(一般采用 URL 编码)

        (2)在 Tomcat 8 之后,cookie 支持中文数据。

              但是对特殊字符(如:空格等)还是不支持,建议使用 URL 编码存储,用URL解码解析。

      4、cookie 共享问题?

        假设在一个 Tomcat 服务器中,部署了多个 web 项目,那么在这些 web 项目中 cookie 能不能共享?

         默认情况下 cookie 不能共享。

         解决方法:

    setPath(String path)
    

          使用上面的方法可以实现 cookie 共享,设置 cookie 的获取范围。默认情况下,设置当前的虚拟目录。

          如果要在一个服务器间共享,则可以将 path 设置为"/" ,代表一个服务器内都可以共享。

      5、不同的 tomcat 服务器 cookie 之间如何共享?

    setDomain(String path);
    

          通过设置该方法,如果设置一级域名相同,那么多个服务器之间cookie可以共享。

        Demo:

    setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享
    

      

    六、Cookie 的特性

      1、特点

        (1)cookie 存储数据在客户端浏览器,不安全,容易被篡改

        (2)浏览器对于单个 cookie 的大小由限制(4KB左右),而且对同一个域名下的总 cookie 的数量也有限制(20个)

      2、作用

        (1)cookie 一般用于存储少量的不太敏感的数据;

        (2)在不登录的情况下,完成服务器对客户端的身份识别;

      3、缺点

        (1)Cookie 是为请求或响应报文发送,无形中增加了网络流量;

        (2)Cookie 是明文传送的安全性差;

        (3)各个浏览器对 Cookie 有限制,使用上有限制;

  • 相关阅读:
    实战篇之实现 OutLook 中以 EDM 形式发送通知邮件
    ASP.NET MVC5 之路由器
    ASP.NET MVC5 之数据迁移
    说不出的烦
    ASP.NET MVC5 之 Log4Net 的学习和使用
    读取配置文件参数和文件路径
    序列化和反序列化示例
    面向对象之封装
    面向对象4之常用的乱七八糟
    面向对象三之继承和派生
  • 原文地址:https://www.cnblogs.com/niujifei/p/11622456.html
Copyright © 2020-2023  润新知