阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

会话跟踪技术-cookie

353次阅读
没有评论

共计 8749 个字符,预计需要花费 22 分钟才能阅读完成。

1、会话跟踪技术

1.1、什么是会话跟踪技术

我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应。例如你给 10086 打个电话,你就是客户端,而 10086 服务人员就是服务器了。从双方接通电话那一刻起,会话就开始了,到某一方挂断电话表示会话结束。在通话过程中,你会向 10086 发出多个请求,那么这多个请求都在一个会话中。

在 JavaWeb 中,客户向某一服务器发出第一个请求开始,会话就开始了,直到客户关闭了浏览器会话结束。

在一个会话的多个请求中共享数据,这就是会话跟踪技术。例如在一个会话中的请求如下:

  • 请求银行主页;

  • 请求登录(请求参数是用户名和密码);

  • 请求转账(请求参数与转账相关的数据);

  • 请求信誉卡还款(请求参数与还款相关的数据)。

在这上会话中当前用户信息必须在这个会话中共享的,因为登录的是张三,那么在转账和还款时一定是相对张三的转账和还款!这就说明我们必须在一个会话过程中有共享数据的能力。

1.2、会话路径技术使用 Cookie 或 session 完成

我们知道 HTTP 协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态。但 HTTP 协议中可以使用 Cookie 来完成会话跟踪!

在 JavaWeb 中,使用 session 来完成会话跟踪,session 底层依赖 Cookie 技术。

2、Cookie

2.1、什么叫 Cookie

Cookie 翻译成中文是小甜点,小饼干的意思。在 HTTP 中它表示服务器送给客户端浏览器的小甜点。其实 Cookie 就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把 Cookie 保存起来,当下一次再访问服务器时把 Cookie 再发送给服务器。
会话跟踪技术 -cookie

Cookie 是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存 Cookie,并会标注出 Cookie 的来源(哪个服务器的 Cookie)。当客户端向服务器发出请求时会把所有这个服务器 Cookie 包含在请求中发送给服务器,这样服务器就可以识别客户端了!

2.2、Cookie 规范

  • Cookie 大小上限为 4KB;

  • 一个服务器最多在客户端浏览器上保存 20 个 Cookie;

  • 一个浏览器最多保存 300 个 Cookie;

上面的数据只是 HTTP 的 Cookie 规范,但在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己的能力起见,可能对 Cookie 规范“扩展”了一些,例如每个 Cookie 的大小为 8KB,最多可保存 500 个 Cookie 等!但也不会出现把你硬盘占满的可能!

注意,不同浏览器之间是不共享 Cookie 的。也就是说在你使用 IE 访问服务器时,服务器会把 Cookie 发给 IE,然后由 IE 保存起来,当你在使用 FireFox 访问服务器时,不可能把 IE 保存的 Cookie 发送给服务器。

2.3、Cookie 与 HTTP 头

Cookie 是通过 HTTP 请求和响应头在客户端和服务器端传递的:

Cookie:请求头,客户端发送给服务器端;

格式:Cookie: a=A; b=B; c=C。即多个 Cookie 用分号离开;

Set-Cookie:响应头,服务器端发送给客户端;

一个 Cookie 对象一个 Set-Cookie:

  • Set-Cookie: a=A

  • Set-Cookie: b=B

  • Set-Cookie: c=C

2.4、Cookie 的覆盖

如果服务器端发送重复的 Cookie 那么会覆盖原有的 Cookie,例如客户端的第一个请求服务器端发送的 Cookie 是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个 Cookie,即:a=AA。

2.5、Cookie 第一例

我们这个案例是,客户端访问 AServlet,AServlet 在响应中添加 Cookie,浏览器会自动保存 Cookie。然后客户端访问 BServlet,这时浏览器会自动在请求中带上 Cookie,BServlet 获取请求中的 Cookie 打印出来。

会话跟踪技术 -cookie

AServlet.java

import java.io.IOException; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 给客户端发送 Cookie * @author Administrator * */ public class AServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8"); String id = UUID.randomUUID().toString();// 生成一个随机字符串 Cookie cookie = new Cookie("id", id);// 创建 Cookie 对象,指定名字和值 response.addCookie(cookie);// 在响应中添加 Cookie 对象 response.getWriter().print("已经给你发送了 ID"); } }

BServlet.java

import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 获取客户端请求中的 Cookie * @author Administrator * */ public class BServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8"); Cookie[] cs = request.getCookies();// 获取请求中的 Cookie if(cs != null) {// 如果请求中存在 Cookie for(Cookie c : cs) {// 遍历所有 Cookie if(c.getName().equals("id")) {// 获取 Cookie 名字,如果 Cookie 名字是 id response.getWriter().print("您的 ID 是:" + c.getValue());// 打印 Cookie 值 } } } } }

2.6、Cookie 的生命

Cookie 不只是有 name 和 value,Cookie 还是生命。所谓生命就是 Cookie 在客户端的有效时间,可以通过 setMaxAge(int)来设置 Cookie 的有效时间。

​ cookie.setMaxAge(-1):cookie 的 maxAge 属性的默认值就是 -1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么 cookie 就会消失。

​ cookie.setMaxAge(60*60):表示 cookie 对象可存活 1 小时。当生命大于 0 时,浏览器会把 Cookie 保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie 也会存活 1 小时;

​ cookie.setMaxAge(0):cookie 生命等于 0 是一个特殊的值,它表示 cookie 被作废!也就是说,如果原来浏览器已经保存了这个 Cookie,那么可以通过 Cookie 的 setMaxAge(0)来删除这个 Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个 Cookie。

2.7、浏览器查看 Cookie

下面是浏览器查看 Cookie 的方式:

IE 查看 Cookie 文件的路径:C:\Documents and Settings\Administrator\Cookies;

FireFox 查看 Cooke:

会话跟踪技术 -cookie

Google 查看 Cookie:

会话跟踪技术 -cookie

会话跟踪技术 -cookie

会话跟踪技术 -cookie

会话跟踪技术 -cookie

2.8、案例:显示上次访问时间

创建 Cookie,名为 lasttime,值为当前时间,添加到 response 中;

在 AServlet 中获取请求中名为 lasttime 的 Cookie;

如果不存在输出“您是第一次访问本站”,如果存在输出“您上一次访问本站的时间是 xxx”;

AServlet.java

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=utf-8"); Cookie cookie = new Cookie("lasttime", new Date().toString()); cookie.setMaxAge(60 * 60); response.addCookie(cookie); Cookie[] cs = request.getCookies(); String s = "您是首次访问本站!"; if(cs != null) {for(Cookie c : cs) {if(c.getName().equals("lasttime")) {s = "您上次的访问时间是:" + c.getValue();} } } response.getWriter().print(s); }

2.9、Cookie 的 path

现在有 WEB 应用 A,向客户端发送了 10 个 Cookie,这就说明客户端无论访问应用 A 的哪个 Servlet 都会把这 10 个 Cookie 包含在请求中!但是也许只有 AServlet 需要读取请求中的 Cookie,而其他 Servlet 根本就不会获取请求中的 Cookie。这说明客户端浏览器有时发送这些 Cookie 是多余的!

可以通过设置 Cookie 的 path 来指定浏览器,在访问什么样的路径时,包含什么样的 Cookie。

2.10、Cookie 路径与请求路径的关系

下面我们来看看 Cookie 路径的作用:

下面是客户端浏览器保存的 3 个 Cookie 的路径:

a: /cookietest;

b: /cookietest/servlet;

c: /cookietest/jsp;

下面是浏览器请求的 URL:

A: http://localhost:8080/cookietest/AServlet;

B: http://localhost:8080/cookietest/servlet/BServlet;

C: http://localhost:8080/cookietest/servlet/CServlet;

请求 A 时,会在请求中包含 a;

请求 B 时,会在请求中包含 a、b;

请求 C 时,会在请求中包含 a、c;

也就是说,请求路径如果包含了 Cookie 路径,那么会在请求中包含这个 Cookie,否则不会请求中不会包含这个 Cookie。

A 请求的 URL 包含了“/cookietest”,所以会在请求中包含路径为“/cookietest”的 Cookie;

B 请求的 URL 包含了“/cookietest”,以及“/cookietest/servlet”,所以请求中包含路径为“/cookietest”和“/cookietest/servlet”两个 Cookie;

B 请求的 URL 包含了“/cookietest”,以及“/cookietest/jsp”,所以请求中包含路径为“/cookietest”和“/cookietest/jsp”两个 Cookie;

2.11、设置 Cookie 的路径

设置 Cookie 的路径需要使用 setPath()方法,例如:

cookie.setPath(“/cookietest/servlet”);

如果没有设置 Cookie 的路径,那么 Cookie 路径的默认值当前访问资源所在路径,例如:

l 访问 http://localhost:8080/cookietest/AServlet 时添加的 Cookie 默认路径为 /cookietest;

l 访问 http://localhost:8080/cookietest/servlet/BServlet 时添加的 Cookie 默认路径为 /cookietest/servlet;

l 访问 http://localhost:8080/cookietest/jsp/BServlet 时添加的 Cookie 默认路径为 /cookietest/jsp;

2.12、Cookie 的 domain

Cookie的 domain 属性可以让网站中二级域共享 Cookie,次要!

百度你是了解的对吧!

http://www.baidu.com

http://zhidao.baidu.com

http://news.baidu.com

http://tieba.baidu.com

现在我希望在这些主机之间共享 Cookie(例如在 www.baidu.com 中响应的 cookie,可以在 news.baidu.com 请求中包含)。很明显,现在不是路径的问题了,而是主机的问题,即域名的问题。处理这一问题其实很简单,只需要下面两步:

  • 设置 Cookie 的 path 为“/”:c.setPath(“/”);

  • 设置 Cookie 的 domain 为“.baidu.com”:c.setDomain(“.baidu.com”)。

当 domain 为“.baidu.com”时,无论前缀是什么,都会共享 Cookie 的。但是现在我们需要设置两个虚拟主机:www.baidu.com 和 news.baidu.com。

第一步:设置 windows 的 DNS 路径解析

找到 C:\WINDOWS\system32\drivers\etc\hosts 文件,添加如下内容

127.0.0.1       localhost
127.0.0.1       www.baidu.com
127.0.0.1       news.baidu.com

第二步:设置 Tomcat 虚拟主机

找到 server.xml 文件,添加 元素,内容如下:

<Host name="www.baidu.com" appBase="F:\webapps\www" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"/> <Host name="news.baidu.com" appBase="F:\webapps\news" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"/>

第三步:创建 A 项目,创建 AServlet,设置 Cookie。

Cookie c = new Cookie("id", "baidu"); c.setPath("/"); c.setDomain(".baidu.com"); c.setMaxAge(60*60); response.addCookie(c); response.getWriter().print("OK");

把 A 项目的 WebRoot 目录复制到 F:\webapps\www 目录下,并把 WebRoot 目录的名字修改为 ROOT。

第四步:创建 B 项目,创建 BServlet,获取 Cookie,并打印出来。

Cookie[] cs = request.getCookies(); if(cs != null) {for(Cookie c : cs) {String s = c.getName() + ":" + c.getValue() + "<br/>"; response.getWriter().print(s); } }

把 B 项目的 WebRoot 目录复制到 F:\webapps\news 目录下,并把 WebRoot 目录的名字修改为 ROOT。

第五步:访问 www.baidu.com\AServlet,然后再访问 news.baidu.com\BServlet。

2.13、Cookie 中保存中文

Cookie 的 name 和 value 都不能使用中文,如果希望在 Cookie 中使用中文,那么需要先对中文进行 URL 编码,然后把编码后的字符串放到 Cookie 中。

向客户端响应中添加 Cookie

String name = URLEncoder.encode("姓名", "UTF-8"); String value = URLEncoder.encode("张三", "UTF-8"); Cookie c = new Cookie(name, value); c.setMaxAge(3600); response.addCookie(c);

从客户端请求中获取 Cookie

response.setContentType("text/html;charset=utf-8"); Cookie[] cs = request.getCookies(); if(cs != null) {for(Cookie c : cs) {String name = URLDecoder.decode(c.getName(), "UTF-8"); String value = URLDecoder.decode(c.getValue(), "UTF- 8"); String s = name + ":" + value + "<br/>"; response.getWriter().print(s); } }

2.14、显示曾经浏览过的商品

index.jsp

<body> <h1> 商品列表 </h1> <a href="/day06_3/GoodServlet?name=ThinkPad">ThinkPad</a><br/> <a href="/day06_3/GoodServlet?name=Lenovo">Lenovo</a><br/> <a href="/day06_3/GoodServlet?name=Apple">Apple</a><br/> <a href="/day06_3/GoodServlet?name=HP">HP</a><br/> <a href="/day06_3/GoodServlet?name=SONY">SONY</a><br/> <a href="/day06_3/GoodServlet?name=ACER">ACER</a><br/> <a href="/day06_3/GoodServlet?name=DELL">DELL</a><br/> <hr/> 您浏览过的商品:<% Cookie[] cs = request.getCookies(); if(cs != null) {for(Cookie c : cs) {if(c.getName().equals("goods")) {out.print(c.getValue()); } } } %> </body>

GoodServlet

public class GoodServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String goodName = request.getParameter("name"); String goods = CookieUtils.getCookValue(request, "goods"); if(goods != null) {String[] arr = goods.split(","); Set<String> goodSet = new LinkedHashSet(Arrays.asList(arr)); goodSet.add(goodName); goods = goodSet.toString(); goods = goods.substring(1, goods.length() - 1); } else {goods = goodName;} Cookie cookie = new Cookie("goods", goods); cookie.setMaxAge(1 * 60 * 60 * 24); response.addCookie(cookie); response.sendRedirect("/day06_3/index.jsp"); } }

CookieUtils

public class CookieUtils {public static String getCookValue(HttpServletRequest request, String name) {Cookie[] cs = request.getCookies(); if(cs == null) {return null; } for(Cookie c : cs) {if(c.getName().equals(name)) {return c.getValue();} } return null; } }

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-06-06发表,共计8749字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7982429
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
【开源神器】微信公众号内容单篇、批量下载软件

【开源神器】微信公众号内容单篇、批量下载软件

【开源神器】微信公众号内容单篇、批量下载软件 大家好,我是星哥,很多人都希望能高效地保存微信公众号的文章,用于...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
【1024程序员】我劝你赶紧去免费领一个AWS、华为云等的主机

【1024程序员】我劝你赶紧去免费领一个AWS、华为云等的主机

【1024 程序员】我劝你赶紧去免费领一个 AWS、华为云等的主机 每年 10 月 24 日,程序员们都会迎来...
从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统

从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统

从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统 大家好,我是星哥。公司的项目文档存了一堆 ...
2025年11月28日-Cloudflare史诗级事故:一次配置失误,引爆全球宕机

2025年11月28日-Cloudflare史诗级事故:一次配置失误,引爆全球宕机

2025 年 11 月 28 日 -Cloudflare 史诗级事故: 一次配置失误,引爆全球宕机 前言 继今...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站 - 手机博物馆 -CHAZ 3D Experience 一句话介绍:一个用 3D 方式重温...
安装并使用谷歌AI编程工具Antigravity(亲测有效)

安装并使用谷歌AI编程工具Antigravity(亲测有效)

  安装并使用谷歌 AI 编程工具 Antigravity(亲测有效) 引言 Antigravity...
星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定!

星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定!

星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定! 前言 作为 NAS 玩家,你是否总被这些...
星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛 NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手! 作为动漫爱好者,你是否还在为...
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...