• 板块一 Servlet编程:第五节 Cookie对象全解 来自【汤米尼克的JAVAEE全套教程专栏】


    上一节中我们学完了Servlet的service()的两个形参,也就是HttpServletRequest和HttpServletResponse两大对象的实例,通过这两个对象可以实现Web交互在后端的请求响应功能。从这一节开始,我们将详解Servlet传递、保存数据的功能,Servlet的第三个对象:Cookie

    一、什么是Cookie

    我们在网上冲浪时,有时登录一个网站之前,会跳出一个Cookie允许弹出,在浏览器的设置中,也有Cookie是否保存的开关,保存登录密码就是用Cookie实现的,那么这个Cookie究竟是什么?在Web交互过程中起到了什么作用?
    在这里插入图片描述
    这件事还要从 第一节 HTTP协议理论与服务器请求响应原理 说起,在那一小节中,我们说HTTP是无状态协议,即协议对于事务处理没有记忆能力,这样有利于HTTP协议的简单性,但对于Servlet这就显得乏善可陈了,因为这意味着我们每一个会话的数据传输量会增大。举个栗子,就像我们下班回家的时候,小区大门的保安大爷每天都要问你是几栋几单元哪户的才给你放行,真是麻烦,有一天你跑去物业那里办了一张门禁卡,终于可以自由进出小区门了,这张门禁卡就是Cookie

    • Cookie是浏览器提供的一种技术,通过服务器的程序能将一些只须保存在客户端,或把在客户端进行处理的数据放在本地的计算机上,不需要通过网络传输进而提高网页处理的效率,减少服务器的负载,但是由于Cookie是服务器端保存在客户端的信息,所以其安全性也是很差的。例如常见的记住密码功能则可以通过Cookie
      来实现
    • Servlet中,有一个专门操作Cookie的类javax.servlet.http.Cookie,随着服务器端的响应发送给客户端,保存在浏览器。当下次再访问服务器时把Cookie再带回服务器

    实例:在开发者工具中查看Cookie是怎样保存的
    还是以百度一下为例,
    可以在响应头键值对里看见一个名为Set-Cookie的键,实际上当前 Cookie有两个版本,分别对应两种设置响应头:Set-CookieSet-Cookie2
    在这里插入图片描述
    但在Servlet中并不支持Set-Cookie2,所以我们来看看Set-Cookie的属性项
    在这里插入图片描述

    同样可以在请求头键值对里看见一个名为Cookie的键里储存着看不懂的值,Cookie在请求头键值对里的格式:键值对用=链接,多个键值对间通过;隔开
    在这里插入图片描述
    或者在应用中查看当前存储着的Cookie,也能发现很多看不懂的键值对
    在这里插入图片描述

    Cookie的源码

    我们来看看Cookie的部分源码,使用注释详解

    public class Cookie implements Cloneable, Serializable {
    
    	// final修改字段不可重写
        private static final CookieNameValidator validation;
        private static final long serialVersionUID = 1L;
        // 定义Cookie的名字变量
        private final String name;
        // 定义Cookie的值变量
        private String value;
        // 版本信息
        private int version = 0;
        private String comment;
        // 域名
        private String domain;
        // 过期时间
        private int maxAge = -1;
        private String path;
        private boolean secure;
        private boolean httpOnly;
    
        // Cookie的构造函数,可以看出是带参构造,必须要实现两个形参name和value
        public Cookie(String name, String value) {
            validation.validate(name);  // name的唯一校验
            this.name = name;
            this.value = value;
        }
        
    。。。再往下就是上面字段的get(),set()方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    二、Cookie的具体操作

    (1)创建Cookie

    通过 new Cookie("key","value");来创建一个Cookie对象,要想将Cookie随响应发送到客户端,需要先添加到Response对象中:Response.addCookie(cookie);此时该Cookie对象则随着响应发送至了客户端。在浏览器上可以被看见

    实例
    在satrt.java中导入javax.servlet.http.Cookie,写入测试代码

    package www.caijiyuan;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import javax.servlet.http.Cookie;
    
    @WebServlet("/start")
    public class start extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 创建Cookie对象
            Cookie cookie = new Cookie("Cooikename", "Cookievalue");
            // 发送Cookie对象
            resp.addCookie(cookie);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    启动服务器,在浏览器中访问start,在开发者工具中就可以获取到当前Cookie的键值了
    在这里插入图片描述

    (2)获取Cookie

    Cookie的获取只能通过Cookie数组遍历来取得,不能单独拎一个出来
    通过Request对象的getCookies()方法调用获得Cookie数组,然后用get()方法取得键值

    Cookie[] cookies = request.getCookies();
    cookie.getName();
    cookie.getValue();
    
    • 1
    • 2
    • 3

    实例:在after.java中获取start.java中存储的Cookie值
    after.java中导入javax.servlet.http.Cookie,写入测试代码

    package www.caijiyuan;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import javax.servlet.http.Cookie;
    @WebServlet("/after")
    public class after extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 获取cookie数组
            Cookie[] cookies = req.getCookies();
            //判断cookie是否为空
            if (cookies != null && cookies.length > 0) {
                //遍历cookie数组
                for (Cookie cookie : cookies) {
                    // 获取cookie的名称和值
                    String Cookiename = cookie.getName();
                    String Cookievalue = cookie.getValue();
                    System.out.println("键:" + Cookiename + ",值:" + Cookievalue);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    启动服务器,在浏览器中先后访问start和after,即可在控制台得到
    在这里插入图片描述
    这就获取到了Cookie

    (3)设置Cookie的到期时间

    Cookie是浏览器的技术,与服务器无关,服务器的关闭、重启都不影响Cookie的值,Cookie的死亡与我们设置的到期时间有关。可以通过手动设定Cookie的有效时间,setMaxAge(int time);方法设定cookie的最大有效时间,以秒为单位。默认为当前浏览器关闭即失效
    到期时间的取值

    • 负整数
      若为负数,表示不存储该Cookie。
      Cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活,一旦关闭浏览器窗口Cookie就会消失
    • 正整数
      若大于0的整数,表示存储的秒数。
      此时浏览器会把Cookie保存到硬盘上,就算关闭浏览器、重启客户端电脑,Cookie也会存活相应的时间。
    • 若为0,表示删除该 Cookie。
      如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。

    实例:在start.java的代码段中为Cookie实例加入设置存活时间的方法setMaxAge()

    // 创建Cookie对象
    Cookie cookie = new Cookie("Cooikename", "Cookievalue");
    // 设置存活时间
    cookie.setMaxAge(30);
    // 发送Cookie对象
    resp.addCookie(cookie);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    启动服务器,在浏览器中访问start,即可中在开发者工具中查看当前Cookie的到期时间的时间戳

    (4)设置Cookie的路径

    Cookie的setPath设置cookie的路径,这个路径直接决定服务器的请求是否会从浏览器中加载某些cookie

    • 情景一:当前Tomcat服务器下任何项目(站点)的任意资源都可获取Cookie对象
    Cookie cookie = new Cookie("xxx", "xxx");
    // 设置路径为”/",表示在当前服务器下任何项目都可访问到cookie对象
    cookie.setPath("/");
    response.addcookie(cookie);
    
    • 1
    • 2
    • 3
    • 4
    • 情景二:指定项目(站点)下的资源可获取Cookie对象(不设置Cookie的path时)
    Cookie cookie = new Cookie("xxx", "xxx");
    // 设置路径为"/start”,表示当前项目可全部访问到cookie对象
    cookie.setPath("/ www.caijiyuan");// 默认如此
    cookie.setPath("/xxx");// 表示指定站点xxx下的资源可以获取Cookie对象
    response.addcookie(cookie);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    例如当前站点就是 www.caijiyuan
    在这里插入图片描述
    一个Tomcat服务器下可能有很多个站点,一个站点和里面的资源的结构就是这样
    在这里插入图片描述

    • 情景三:指定项目(站点)下的某个资源可获取Cookie对象
    Cookie cookie = new Cookie("xxx", "xxx");
    // 设置路径为"/www.caijiyuan/start",表示在/www.caijiyuan/start目录下才可访问到Cookie对象
    cookie.setPath("/www.caijiyuan/start");
    response.addcookie(cookie);
    
    • 1
    • 2
    • 3
    • 4

    如果我们设置path时当前访问的路径包含了Cookie的路径(当前访问路径要比Cookie的范围小)Cookie就会加载到Request对象之中。当访问的路径包含了Cookie的路径时,则该请求将带上该Cookie,如果访问路径不包含Cookie路径,则请求不会携带该Cookie

    三、Cookie的相关事项

    • Cookie保存在当前浏览器中
      Cookie操作只是将信息保存在本机上,换电脑或跨浏览器后以后这些信息就失效了
    • Cookie存中文问题
      Cookie 中不能出现中文,如果有中文则通过URLEncoder.encode()来进行编码,获取时通过URLDecoder.decode()来进行解码。

    实例
    保存时编码

    String Cookiename="姓名";
    String Cookievalue="汤米尼克";
    // 通过 URLEncoder.encode()来进行编码
    Cookiename= URLEncoder.encode(Cookiename);
    Cookievalue= URLEncoder.encode(Cookievalue);
    // 创建Cookie对象
    Cookie cookie = new Cookie(Cookiename,Cookievalue);
    // 发送Cookie对象
    response.addcookie(cookie);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    获取时解码

    // 获取时通过 URLDecoder.decode()来进行解码
    URLDecoder.decode(cookie.getName());
    URLDecoder.decode(cookie.getValue());
    
    • 1
    • 2
    • 3
    • 同名Cookie问题
      如果服务器端发送重复的Cookie(名称)那么会覆盖原有的Cookie
    • 浏览器存储Cookie问题
      不同的浏览器对Cookie有不同的存储上限,一般大小上限4KB左右。Cookie是存储在客户端(浏览器)的,由服务器端创建和设定。后期结合Session来实现回话跟踪。

    以上就是本小节的所有内容,但Cookie是有大小限制和数量限制的,并且越来越多的Cookie代表客户端和服务器的传输量增加,可不可以每次传的时候不传所有cookie值,而只传一个唯一ID,通过这个ID直接在服务器查找用户信息呢?答案是有的,这就是我们的session,在下一节中我们来详解session

  • 相关阅读:
    双指针算法_移动零_
    关于SpringBoot项目中读取不到自建email.yml配置文件内容的问题
    Python入门【序列、列表简介、列表的创建 、列表元素的增加、列表元素的删除 】(四)-全面详解(学习总结---从入门到深化)
    App测试中iOS和Android的差异
    ==和equals的对比
    Springboot集成kafka高级应用实战
    图嵌入概述:节点、边和图嵌入方法及Python实现
    图像处理QPixmap、Picture、QBitmap
    为什么说网上的md5加密解密站都是通过彩虹表解密的?
    prompt 综述
  • 原文地址:https://blog.csdn.net/Tommy_Nike/article/details/136135295