大佬:https://www.cnblogs.com/moyand/p/9047978.html
在 http 协议一个很大的缺点就是不对用户身份的进行判断,这样给编程人员带来很大的不便, 而 cookie 功能的出现弥补了这个不足。
cookie 就是在客户访问脚本的同时,通过客户的浏览器,在客户硬盘上写入纪录数据 ,当下次客户访问脚本时取回数据信息,从而达到身份判别的功能,cookie 常用在身份校验中。
这句话说明cookie是前端浏览器帮我们做的事情。同时人家访问服务器的时候还会携带上cookie
request是Servlet.service()方法的一个参数,在客户端发出每个请求时,服务器都会创建一个request对象,并把请求数据封装到request中,然后在调用Servlet.service()方法时传递给service()方法
session可以理解为request下面的用来存储数据的对象
从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,称为一次会话
首先,为什么需要会话机制?
会话机制最主要的目的是帮助服务器记住客户端状态(标识用户,跟踪状态)。目前,客户端与服务器的通讯都是通过HTTP协议。而HTTP是一种无状态协议。什么叫无状态?就是客户端第二次来访时,服务器根本不知道这个客户端以前是否来访过,Web服务器本身不能识别出哪些请求是同一个浏览器发出的。即:浏览器的每一次请求都是完全孤立的。
为了更好的用户体验(比如实现购物车),就有了会话机制。有了它,服务器可以记住并区分客户端,把同一个客户端的操作归类在一起。否则我用我的电脑在京东买了东西,你用你的电脑打开京东却发现购物车里塞满了商品,你乐意吗?
这里再举一个例子:假设我们注册了一个论坛,因为HTTP是无状态的,服务器无法辨认访问者,那么即使是同一个网站的不同页面,服务器都必须强制访问者重新登录一次,以确定你是合法用户…
所以,会话机制显得很有必要。由于某些原因,HTTP必须保持无状态,所以会话跟踪技术就成了对HTTP无状态协议的一种扩展。
其次,如何定义一个会话?
基于上面的分析(会话是为了唯一标识一个用户并记录其状态),既然一个会话可以帮助服务器断定一个客户端,那么反向推导得到的结论就是:当服务器无法断定客户端时,一次会话就结束了!
服务器什么情况下无法断定一个客户端?无非两种情况:
服务器不行了(session失效)客户端不行了(cookie失效)
又基于上面分析,可以总结出会话的基本原则:
双方共存(cookie与session同在)
什么意思?先举个生活中的例子:我给隔壁老王打电话。这是我和老王之间的会话。因为满足上面基本原则:
我和老王在交互信息(我和老王的之间的会话,双方共存)
什么时候我和老王的会话结束呢?
老王或我的手机没电了(双方不共存)
这是现实的例子,很容易理解,而且会话这个概念本来就来自现实生活。但是客户端和服务器该如何模拟这样的会话呢?
认识Cookie
在Java的世界里,会话跟踪常用的有两种技术:Cookie和Session,并且Session底层依赖于Cookie。
当然啦,如果Cookie被禁用,也可以通过URL重写等手段实现,但这里不涉及。因为只要你真的明白这篇文章所讲的全部内容,URL重写理解起来很简单。
我希望大家在看接下来的文字时,要始终提醒自己会话机制的目的是什么:标识用户,跟踪状态。
先来看一下生活中的一个场景:你约人去下馆子。那个馆子远近闻名,每天都要接待很多顾客,座无虚席。于是你打算早一点去店里预定位置。店门口有一台取号机。稍早些到店里的顾客,店员会用取号机打印一张票据给客人,上面记录了一些信息。此时距离约定就餐时间还有段时间,于是你打算去附近西湖逛逛。当你逛完西湖回来时,把票据交给店员,店员一看票据:bravo1988,18:00,69桌。于是把你领到指定位置就餐。
所谓Cookie,可以通俗地理解为上面取号机给的票据。
从编程的角度来讲,Cookie其实是一份小数据,是服务器响应给客户端,并且存储在客户端的一份小数据。下次客户端访问服务器时,会自动带上这个Cookie。服务器通过Cookie就可以区分客户端。
服务器端如何将Cookie发给浏览器呢?
最简单的代码:服务器端new一个cookie,通过response的addCookie方法响应给浏览器
浏览器访问SendCookieServlet,Servlet通过Response向客户端发送Cookie
response.addCookie()后,实际服务器响应给浏览器时发生了什么?
服务器端(上面编写的Servlet)发给客户端的Cookie最终以HTTP响应形式发送,也就是Set-Cookie响应头。
浏览器接收到这些响应头后,会把它们作为Cookie文件存在客户端。当我们第二次请求同一个服务器,浏览器在发送HTTP请求时,会带上这些Cookie。
因为现在客户端已经有Cookie了,所以往后每次访问该服务器,都会带上这个Cookie。那么,如何在服务器端得到客户端带来的Cookie呢?
注意,虽然请求头中cookie的内容是name=brava1988;time=6pm;table=69,但是并不需要我们在Servlet中用分号切割字符串。只要调用request.getCookies();即可得到cookie数组(自动切割成数组)
但是,上面SendCookieServlet的代码有个问题!
此种方式传给客户端的Cookie会随着客户端(浏览器)的关闭而消失。这也就是为什么你登录京东,添加商品进购物车,关闭浏览器重新打开时却要你再次登录的原因。
因为你第一次访问京东登录后,京东服务器给了你的浏览器一个Cookie。当你关闭浏览器时,这个Cookie消失了。所以重新打开京东主页时,服务器找不到证明你登录过的Cookie,就让你重新登录。
Cookie的两种类型
其实Cookie可以分为两种:
会话Cookie (Session Cookie)持久性Cookie (Persistent Cookie)
上面代码中,服务器向浏览器响应的Cookie就是会话Cookie。会话Cookie被保存在浏览器的内存中,当浏览器关闭时,内存被释放,内存中的Cookie自然也就烟消云散。
这样太麻烦了,关闭浏览器引发Cookie消失,下次还要重新登录。能不能向客户端响应持久性Cookie呢?只要设置Cookie的持久化时间即可!
假设现在服务端有当个Session,根据JSESSIONID获取对应的Session
Cookie与Session - bravo1988的文章 - 知乎
https://zhuanlan.zhihu.com/p/42918845
https://www.bilibili.com/video/BV1ML411x7hY?p=7&spm_id_from=pageDriver