Cookie的工作原理和应用详解

 更新时间:2021年06月21日 11:17:48   作者:不才Jerry  
Cookies是 web站点放置到你的硬盘上的程序。它们驻留在你的计算机上收集关于你在因特网上所做的一切事情的信息,并且 web站点可以在任何时候读取到Cookies收集到的所有信息

1. Cookie 原理

1.1 Cookie 背景信息

客户端状态管理技术,将状态信息保存在客户端。网景公司发明,浏览器会话技术。一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称name和设置值value。浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个大小限制为4kb

1.2 Cookie 工作原理

Cookie工作原理

执行流程:

1.浏览器向服务器发送请求,服务器需要创建cookie,服务器会通过响应携带cookie,在产生响应时会产生Set-Cookie响应头,从而将cookie信息传递给了浏览器;

2.当浏览器再次向服务器发送请求时,会产生cookie请求头,将之前服务器的cookie信息再次发送给了服务器,然后服务器根据cookie信息跟踪客户端状态。

1.3 Cookie 创建、获取、修改

chrome谷歌浏览器查看cookie信息,浏览器地址栏输入:

  • chrome://settings/content/cookies
  • chrome://settings/siteData

Cookie 创建:

// 用响应创建Cookie,等价于 response.addHeader("set-cookie", "name=value");
Cookie cookie = new Cookie(String name, String value); // Cookie: name=value
cookie.setMaxAge(seconds); // 设置Cookie的生命周期
cookie.setPath("/"); // 设置Cookie的共享范围
response.addCookie(cookie); // 添加1个Cookie

Cookie 获取:

// 用请求获取Cookie
Cookie[] cookies = request.getCookies(); // 获取Cookies返回数组
// 需遍历
cookie.getName(); // 获取键
cookie.getValue(); // 获取值

Cookie 修改:

// 修改Cookie
cookie.setValue(String name);

1.4 Cookie 共享范围

/ 当前项目下所有资源均可共享访问该Cookie对象内容

/project/demo 当前项目下只有资源demo均可共享访问该Cookie对象内容

设置 Cookie 数据共享范围:

// 设置Cookie的共享范围
cookie.setPath("/");

1.5 Cookie 生命周期

  • <0:浏览器会话结束/浏览器关闭,内存存储(默认)
  • =0:失效
  • >0:生效时间,单位s

在生命周期内Cookie会跟随任何请求,可通过设置路径限制携带Cookie的请求资源范围

设置 Cookie 数据生命周期:

// 设置Cookie生命周期,单位s
cookie.setMaxAge(int second); // 7天:7*24*60*60

1.6 Cookie 中文乱码 - 解决方案

中文:Unicode,4个字节 英文:ASCII,2个字节

Cookie的中文乱码需要进行编码和解码处理:

编码:java.net.URLEncoder 的 URLEncoder.encode(String str, String encoding)

解码:java.net.URLDecoder 的 URLDecoder.decode(String str, String encoding)

// 编码
Cookie cookie = new Cookie(
        URLEncoder.encode("键", "utf-8"),
        URLEncoder.encode("值", "utf-8")
);
response.addCookie(cookie);
// 解码
String keyStr = URLDecoder.decode(cookie.getName(), "utf-8");

1.7 Cookie 优缺特点分析

优点:

可配置到期规则:① 1次请求就失效 ②1次浏览器会话(关闭)失效 ③配置永久生效 ● 简单性:基于文本的轻量结构,简单键值对

数据持久性:虽然Cookie可被客户端浏览器的过期处理和干预,但Cookie通常也是客户端上持续时间最长的数据保留形式缺点:

大小受到限制:大多数浏览器的Cookie只有4kb大小的限制

用户配置禁用:客户浏览器设置了禁用接收Cookie的能力,限制了该功能

潜在安全风险:用户可能会操纵篡改浏览器上的Cookie,会造成Cookie应用程序执行失败的问题

2. Cookie 应用

2.0 工具类:CookieUtils

public class CookieUtils {
    /**
     * 获取指定名称的Cookie对象
     * @param cookies 一组Cookie
     * @param cookieName 指定的Cookie名称
     * @return 需要的Cookie
     */
    public static Cookie getCookie(Cookie[] cookies, String cookieName) {
        if (null != cookies && 0 != cookies.length) {
            for (Cookie ck : cookies) {
                if (cookieName.equals(ck.getName())) {
                    return ck;
                }
            }
        }
        return null;
    }
}

2.1 案例:记录用户上一次访问时间

核心逻辑:

    // 判断是否是第一次请求
    Cookie cookie = CookieUtils.getCookie(request.getCookies(), "lastTime");
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    if (null == cookie) {
        // 第一次访问,打印当前时间,并创建Cookie,存储当前时间
        Date date = new Date();
        System.out.println("第一次访问时间:" + sdf.format(date));
        cookie = new Cookie("lastTime", String.valueOf(date.getTime()));
    } else {
        // 不是第一次访问,从cookie去除上一次访问时间,并打印,获取当前时间,存储cookie中
        long currTimeMills = Long.parseLong(cookie.getValue());
        System.out.println("上一次访问时间:" + sdf.format(new Date(currTimeMills)));
        cookie.setValue(String.valueOf((new Date()).getTime()));
    }
    response.addCookie(cookie);

Cookie应用

2.2 案例:记录商品的浏览历史信息

历史记录核心逻辑:

    String id = request.getParameter("id");
    Cookie cookie = CookieUtils.getCookie(request.getCookies(), "history");
    if (null == cookie) {
        // 木有浏览记录:创建Cookie,并存储浏览记录
        cookie = new Cookie("history", id);
    } else {
        // 有浏览记录
        String history = cookie.getValue();
        if (!history.contains(id)) {
            // 有浏览记录,不包含当前浏览商品:将浏览商品拼接到已有的浏览记录中
            history += "-" + id;
            cookie.setValue(history);
        }
        // 有浏览记录,包含当前浏览商品则无需处理
    }
    response.addCookie(cookie);
    // 显示商品浏览记录,路径:/demo/show
    response.sendRedirect(request.getContextPath() + File.separator + "show");

显示历史记录信息:

        // 获取商品浏览记录
        Cookie cookie = CookieUtils.getCookie(request.getCookies(), "history");
        StringBuffer respsb = new StringBuffer();
        if (null == cookie) {
            // 没有浏览记录
            respsb.append("<font color='red'>没有浏览记录</font>,");
            respsb.append("<a href='books.html'>浏览商品</a>");
        } else {
            // 有浏览记录: 0-1-2-3
            String[] books = {"西游记", "红楼梦", "水浒传", "三国志"};
            String history = cookie.getValue();
            String[] historys = history.split("-");
            respsb.append("您的浏览记录如下:<br>");
            for (String index : historys) {
                String bookName = books[Integer.parseInt(index)];
                respsb.append(bookName).append("<br>");
            }
        }
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println(respsb);

Cookie应用

点击第一个后:

Cookie应用

总结

本篇文章的内容就到这了,希望大家可以多多关注脚本之家的其他精彩内容!

相关文章

  • java实现mongodb的数据库连接池

    java实现mongodb的数据库连接池

    这篇文章主要介绍了基于java实现mongodb的数据库连接池,Java通过使用mongo-2.7.3.jar包实现mongodb连接池,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • mybatis类型转换器如何实现数据加解密

    mybatis类型转换器如何实现数据加解密

    这篇文章主要介绍了mybatis类型转换器如何实现数据加解密,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 2022年最新java 8 ( jdk1.8u321)安装图文教程

    2022年最新java 8 ( jdk1.8u321)安装图文教程

    这篇文章主要介绍了2022年最新java 8 ( jdk1.8u321)安装图文教程,截止2022年1月,官方出的jdk1.8目前已更新到8u321的版本,本文通过图文并茂的形式给大家介绍安装过程,需要的朋友可以参考下
    2022-08-08
  • Java开发JUC交换器Exchanger使用详解

    Java开发JUC交换器Exchanger使用详解

    这篇文章主要为大家介绍了Java开发JUC交换器Exchanger使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • SpringBoot整合Shiro的环境搭建教程

    SpringBoot整合Shiro的环境搭建教程

    这篇文章主要为大家详细介绍了SpringBoot整合Shiro的环境搭建教程,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以了解一下
    2022-12-12
  • redisson实现分布式锁原理

    redisson实现分布式锁原理

    本文将详细介绍redisson实现分布式锁原理。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • MyBatis-Plus常见面试题和答案大全

    MyBatis-Plus常见面试题和答案大全

    Mybatis-Plus是一个基于Mybatis的增强工具,它简化了Mybatis的开发流程,提供了许多实用的功能,如自动生成代码、分页查询、条件构造器、性能分析等,这篇文章主要给大家介绍了关于MyBatis-Plus常见面试题和答案的相关资料,需要的朋友可以参考下
    2023-06-06
  • Java实现异步延迟队列的方法详解

    Java实现异步延迟队列的方法详解

    目前系统中有很多需要用到延时处理的功能,本文就为大家介绍了Java实现异步延迟队列的方法,文中的示例代码讲解详细,需要的可以参考一下
    2023-03-03
  • springboot快速集成mybatis-plus的详细教程

    springboot快速集成mybatis-plus的详细教程

    这篇文章主要介绍了springboot快速集成mybatis-plus的教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Struts2 Result 返回JSON对象详解

    Struts2 Result 返回JSON对象详解

    这篇文章主要讲解Struts2返回JSON对象的两种方式,讲的比较详细,希望能给大家做一个参考。
    2016-06-06

最新评论