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) 

    原理图:

    

     代码示例:

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

    注意

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

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

  2、服务器获取 Cookie

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

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

      原理图:

    

    代码示例:

     把根据名称查找 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;
}
}

     获取 Cookie: 

 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() + "] <br/>");
}
Cookie iWantCookie = CookieUtils.findCookie("key1", cookies); // 如果不等于 null, 说明赋过值, 也就是找到了需要的 Cookie
if (iWantCookie != null) {
resp.getWriter().write("找到了需要的 Cookie");
}
}

  3、Cookie 值的修改

    方案一:

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

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

      ③ 调用 response.addCookie(Cookie);

    代码示例:

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

    方案二:

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

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

      ③ 调用 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

  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:

 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 细节

  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 有限制,使用上有限制;

Java 之 Cookie的更多相关文章

  1. java对cookie的操作

    java对cookie的操作比较简单,主要介绍下建立cookie和读取cookie,以及如何设定cookie的生命周期和cookie的路径问题. 建立一个无生命周期的cookie,即随着浏览器的关闭即 ...

  2. java之Cookie详解

    Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是 ...

  3. JAVA操作COOKIE

    JAVA操作COOKIE 1.设置Cookie Cookie cookie = new Cookie("key", "value"); cookie.setMa ...

  4. Java 处理cookie的方法

    一.java创建cookie 方法一: Response.Cookies["userName"].Value = "patrick"; Response.Coo ...

  5. java之Cookie具体解释

    Cookie是由server端生成.发送给User-Agent(通常是浏览器).浏览器会将Cookie的key/value保存到某个文件夹下的文本文件内.下次请求同一站点时就发送该Cookie给ser ...

  6. Java web Cookie详解(持久化+原理详解+共享问题+设置中文+发送多个Cookie)

    Java web Cookie详解 啥是cookie? 查询有道词典得: web和饼干有啥关系? 这个谜底等等来为大家揭晓 会话技术 web中的会话技术类似于生活中两个人聊天,不过web中的会话指的是 ...

  7. java中Cookie中文字符乱码问题

    如果Cookie中的Value 中有中文字符出现,在加入Cookie的时候,会出现下面的错误: java.lang.IllegalArgumentException: Control characte ...

  8. PHP Java 设置cookie方法

      Java Cookie cookie = new Cookie(COOKIE_NAME, encrypt_cookieV); cookie.setMaxAge(60 * 60); cookie.s ...

  9. java 使用cookie记录用户上一次访问的时间 记住 用户的 登录名

    package cn.itcast.cookie; import java.io.IOException; import java.io.PrintWriter; import java.util.D ...

  10. Control character in cookie value, consider BASE64 encoding your value , java操作cookie遇到中文会报错的解决方案

    项目当中用到cookie保存中文,但是会报如下错误: Control character in cookie value, consider BASE64 encoding your value 大概 ...

随机推荐

  1. MySQL应用报错:java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction

    开发反馈,某业务系统插入一条记录的时候,日志报错,插入失败: ### Error updating database. Cause: java.sql.SQLException: Lock wait ...

  2. Sequelize模糊查询

    const Sequelize = require('sequelize'); const Op = Sequelize.Op; User.findAll({ raw: true, order: [ ...

  3. Java13新特性 -- 重新实现旧版套接字API

    全新实现的 NioSocketImpl 来替换JDK1.0的PlainSocketImpl. 它便于维护和调试,与 NewI/O (NIO) 使用相同的 JDK 内部结构,因此不需要使用系统本地代码. ...

  4. server computer anaconda

    star@xmatrix:~/Anaconda$ star@xmatrix:~/Anaconda$ conda create -n wind1 python=3.6Solving environmen ...

  5. qt 获取汉字拼音首字母

    #include "mainwindow.h"#include "ui_mainwindow.h"#include <QDebug>#include ...

  6. 关于Oracle报 ORA-00600: 内部错误代码, 参数: [kkqcscpopn_Int: 0], [], [], [], [], [], [], [], [], [], [], []解决

    服务器上有的Oracle版本是11.2.0.1.0,但是用到了mybatis-PageHelper分页插件会报这个错误. 下面说说我是怎么遇到这个错误的:同事写的这个功能点是用到了前台分页,是正常的没 ...

  7. [转帖]/proc/sys目录下各文件参数说明

    /proc/sys目录下各文件参数说明 https://blog.csdn.net/luteresa/article/details/68061881   一.前言 本文档针对OOP8生产环境,具体优 ...

  8. 使用 Redis 的 sorted set 实现用户排行榜

    要求:实现一个用户排行榜,用户数量有很多,排行榜存储的是用户玩游戏的分数,对排行榜的读取压力比较大,如何实现? 思路分析: 实现排行榜,可以考虑使用 Redis 的 zset 结构: 用户数量很多的话 ...

  9. thinkphp 5.0.24 配置多模块注意的细节

    /*index.php 文件  这一段用于生成模块用 build.php 只能生成诸如 admin hotel 开头为小写字母的模块 如果你设定的 大写开头 如 Hotel Admin 系统就会找不到 ...

  10. C++—lambda表达式+优先队列 prority_queue+关键字decltype

    合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入:[  1->4->5,  1->3->4,  2->6]输出: 1->1-&g ...