一文了解Cookie

Cookie

什么是 Cookie?

先要了解HTTP是 无状态的Web服务器,什么是无状态呢?一次对话完成后下一次对话完全不知道上一次对话发生了什么。如果在Web服务器中只是用来管理静态文件还好说,对方是谁并不重要,把文件从磁盘中读取出来发出去即可。但是随着网络的不断发展,比如电商中的购物车只有记住了用户的身份才能够执行接下来的一系列动作。所以此时就需要我们 无状态的服务器记住一些事情。

那么Web服务器是如何记住一些事情呢?既然Web服务器记不住东西,那么我们就在外部想办法记住,相当于服务器给每个客户端都贴上了一个小纸条。上面记录了服务器给我们返回的一些信息。然后服务器看到这张小纸条就知道我们是谁了。那么Cookie是谁产生的呢?Cookies是由服务器产生的。接下来我们描述一下Cookie产生的过程

浏览器第一次访问服务端时,服务器此时肯定不知道他的身份,所以创建一个独特的身份标识数据,格式为key=value,放入到Set-Cookie字段里,随着响应报文发给浏览器。

浏览器看到有Set-Cookie字段以后就知道这是服务器给的身份标识,于是就保存起来,下次请求时会自动将此key=value值放入到Cookie字段中发给服务端。

服务端收到请求报文后,发现Cookie字段中有值,就能根据此值识别用户的身份然后提供个性化的服务。

一文了解Cookie

如何创建 Cookie

一文了解Cookie

Servlet 程序中的代码:

protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1 创建Cookie对象
        Cookie cookie = new Cookie("key4", "value4");
        //2 通知客户端保存Cookie
        resp.addCookie(cookie);
        //1 创建Cookie对象
        Cookie cookie1 = new Cookie("key5", "value5");
        //2 通知客户端保存Cookie
        resp.addCookie(cookie1);

        resp.getWriter().write("Cookie创建成功");
    }

一文了解Cookie

Cookie创建成功!

服务器如何获取 Cookie

服务器获取客户端的 Cookie 只需要一行代码: req.getCookies():Cookie[]

一文了解Cookie

Cookie 的工具类:

public class CookieUtils {
    /**
     * 查找指定名称的 Cookie 对象
     * @param name
     * @param cookies
     * @return
     */
    public static Cookie findCookie(String name , Cookie[] cookies){
        if (name == null || cookies == null || cookies.length == 0) {
            return null;
        }
        for (Cookie cookie : cookies) {
            if (name.equals(cookie.getName())) {
                return cookie;
            }
        }
        return null;
    }
}

Servlet 程序中的代码:

    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Cookie[] cookies = req.getCookies();

        for (Cookie cookie : cookies) {
            // getName方法返回Cookie的key(名)
            // getValue方法返回Cookie的value值
            resp.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "] ");
        }

        Cookie iWantCookie = CookieUtils.findCookie("key1", cookies);
        // 如果不等于null,说明赋过值,也就是找到了需要的Cookie
        if (iWantCookie != null) {
            resp.getWriter().write("找到了需要的Cookie");
        }

    }

一文了解Cookie

Cookie 值的修改

方法一:
1、先创建一个要修改的同名(指的就是 key)的 Cookie 对象
2、在构造器,同时赋于新的 Cookie 值。
3、调用 response.addCookie( Cookie );

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

方法二:

1、先查找到需要修改的 Cookie 对象
2、调用 setValue()方法赋于新的 Cookie 值。
3、调用 response.addCookie()通知客户端保存修改

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

浏览器查看 Cookie(以edge浏览器为例)

在页面空白区域右键,然后点击检查:

一文了解Cookie

一文了解Cookie

Cookie 生命控制

Cookie 的生命控制指的是如何管理 Cookie 什么时候被销毁(删除)
setMaxAge()
正数,表示在指定的秒数后过期
负数,表示浏览器一关,Cookie 就会被删除(默认值是-1)
零,表示马上删除 Cookie

例:

protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
    Cookie cookie = new Cookie("life3600", "life3600");
    cookie.setMaxAge(60 * 60); // 设置 Cookie 一小时之后被删除。无效
    resp.addCookie(cookie);
    resp.getWriter().write(" 已经创建了一个存活一小时的 Cookie");
}
protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
    // 先找到你要删除的 Cookie 对象
    Cookie cookie = CookieUtils.findCookie("key4", req.getCookies());
    if (cookie != null) {
        // 调用 setMaxAge(0);
        cookie.setMaxAge(0); // 表示马上删除,都不需要等待浏览器关闭
        // 调用 response.addCookie(cookie);
        resp.addCookie(cookie);
        resp.getWriter().write("key4 的 的 Cookie 已经被删除");
    }
}
protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
    Cookie cookie = new Cookie("defalutLife","defaultLife");
    cookie.setMaxAge(-1);// 设置存活时间
    resp.addCookie(cookie);
}

Cookie 有效路径 Path 的设置

Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器。哪些不发。
path 属性是通过请求的地址来进行有效的过滤。
CookieA path=/工程路径
CookieB path=/工程路径/abc

请求地址如下:

http://ip:port/工程路径/a.html

CookieA 发送
CookieB 不发送

http://ip:port/工程路径/abc/a.html

CookieA 发送
CookieB 发送

例:

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

Cookie 实操—免输入用户名登录

一文了解Cookie

login.jsp:


    登录页面

        用户名:
        密码:

LoginServlet :

public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        if ("kailong".equals(username) && "123456".equals(password)) {
            //登录 成功
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60 * 60 * 24 * 7);//当前Cookie一周内有效
            resp.addCookie(cookie);
            System.out.println("登录 成功");
        } else {
//            登录 失败
            System.out.println("登录 失败");
        }

    }
}

试验:

第一次登录:

一文了解Cookie

点击登录后,控制台显示登录成功

一文了解Cookie

然后我们关了浏览器再打开这个页面

一文了解Cookie

再打开这个页面可以发现用户名已经存在,这就是cookie保存了用户名信息,然后这里设置的是Cookie有效期为一周,一周后该Cookie就失效了

公众号本文地址:https://mp.weixin.qq.com/s/bv7iIHsUUMFj1LB6F48Jyw

欢迎关注公众号:愚生浅末。

Original: https://www.cnblogs.com/kohler21/p/16700003.html
Author: 愚生浅末
Title: 一文了解Cookie

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/617240/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Spring Boot2配置Swagger2生成API接口文档

    一、Swagger2介绍 前后端分离开发模式中,api文档是最好的沟通方式。Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服…

    Java 2023年6月15日
    062
  • Java入门

    一、Java 1.1 为什么Java是平台无关性(可以跨平台) 二、Java环境 2.1、JRE 2.2、JDK 2.3、JVM 三、Java编译和运行的机制 四、Java基础 4…

    Java 2023年6月7日
    0109
  • 跟着柴毛毛学Spring(3)——简化Bean的配置

    通过前面的学习。我们会感觉到对于一个有较多Bean的大项目,Spring的配置会比較复杂。 那么接下来我们就介绍怎样简化Spring的配置。 简化Spring的配置主要分为两类:1…

    Java 2023年5月30日
    050
  • Google Aviator——轻量级 Java 表达式引擎实战

    表达式引擎技术及比较 Drools 简介 Drools(JBoss Rules )是一个开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师或审核人员可以利用它轻松查看业务规…

    Java 2023年6月15日
    079
  • 力扣刷题之路——二维数组变换、前缀和数组

    刷题顺序参考:力扣刷题顺序 涉及题目 48. 旋转图像 73. 矩阵置零 289. 生命游戏 238. 除自身以外数组的乘积 旋转图像 自己的解题思路: 题目上说不能使用另一个矩阵…

    Java 2023年6月5日
    075
  • Java并发编程艺术系列-四、 Java并发编程基础

    四、 Java并发编程基础 本章将着重介绍Java并发编程的基础知识,从启动一个线程到线程间不同 的通信方式,最后通过简单的线程池示例以及应用(简单的Web服务器)来串联本章所介绍…

    Java 2023年6月9日
    0180
  • Layui 获取日期(今天,前天,后天,当月最后一天)

    var now =new Date (); var year =now .getFullYear ();//获取当前年份 var month =now .getMonth ()+1…

    Java 2023年6月5日
    074
  • Dokcer运行Nacos容器自动退出问题

    Dokcer运行Nacos容器自动退出问题 参考博文 学生党,租的云服务器,2核2G。使用Docker运行Nacos容器的时候发现总是自动退出。Nacos日志里面没有明显的报错信息…

    Java 2023年6月8日
    069
  • JMeter While循环控制器应用之遍历获取文件参数

    作者:授客微信/QQ:1033553122全国软件测试QQ交流群:7156436Git地址:https://gitee.com/ishouke友情提示:限于时间仓促,文中可能存在错…

    Java 2023年6月16日
    057
  • sharepoint 2013 “The module … owssvr.dll could not be loaded due to a configuration problem”

    打开sharepoint站点可以看到这个503的错误, 在event viewer中查看如下: The Module DLL ‘C:\Program Files\Com…

    Java 2023年6月7日
    056
  • 干货分享之Spring框架源码解析01-(xml配置解析)

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正! 环境: spring5.X + idea Spring 是一个工厂,是一个负责对象的创建…

    Java 2023年6月5日
    093
  • java面试——流

    流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。 …

    Java 2023年6月9日
    086
  • Java简介

    J2SE:平台标准版,可以做桌面程序开发 他是整个java技术的基础和核心 J2EE:平台企业版,可以做网站 J2ME:平台微型版,可以做移动端程序开发 简单性:舍弃了c++中难以…

    Java 2023年5月29日
    066
  • 【spring源码学习】@Aspect 实现切面代码的原理

    一、spring-boot框架中的应用 1、服务启动时,会加载spring-boot-autoconfigure的jar中spring.factories文件,加载服务启动自动装配…

    Java 2023年5月29日
    070
  • bsd socket 网络通讯必备工具类

    传输数据的时候都要带上包头,包头有简单的又复杂的,简单的只要能指明数据的长度就够了。 这里我写了一个工具类,可以方便地将整型的数据长度转换为长度为 4 的字节数组。 另一方面,可以…

    Java 2023年5月29日
    074
  • 【软件构造】Java中的接口Interface

    【软件构造】Java中的接口Interface 1.前言 在Lab2中,要求通过Graph接口达到不同种类的实现目标,实验过程中也多次用到了java接口这一概念,编程时涉及了很多需…

    Java 2023年6月5日
    080
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球