概念 |
1. 无状态协议带来的弊端
在了解Cookie之前,首先知道我们在做web开发的时候使用的Http协议是一种无状态协议
,也就是说浏览器向Web服务器发送的每一个请求都是完全独立没有联系的。连续发送两次请求,对于Web服务器端来说不知道两次请求是否来自于同一个用户。
2. 问题案例及解决办法
针对于无状态协议
的特性,往往我们在编程的时候又是需要Web服务器清楚了解自己接收的请求是来自于哪个浏览器。
在浏览器中,我在某宝网站上购买东西,先向自己的购物车中添加一个商品,然后又添加了一个商品,那么这两个商品应该都放在我自己的购物车中,而不是一个商品放张三的购物车中,一个商品给我放到李四的购物车中了,所以此时,Web服务器必须要通过某种方法某种机制来识别并记住我的用户信息,确保我发起的添加商品到购物车
的请求最终会放到我的购物车中。
3. 会话与状态管理
前文所说的这种机制就是会话与状态管理
。
会话:
web浏览器客户端与web服务器端之间连续发生的一系列请求和响应的过程,也就是说:浏览器与服务器之间的一次会话中包含了多次的请求与响应。
会话状态:
web浏览器客户端与web服务器端在会话过程中产生的状态信息。web服务器端能够根据会话状态
将属于同一会话的一系列请求和响应联系起来。
web服务器要想能够识别每次接收到的请求到底是哪个浏览器发送的,那么客户端就需要对发送的请求进行标识,如果是同一个会话,那么请求中附带的标识一样,不同会话的请求信息它的标识号不同。而这个标识号就是SessionID。
4.会话跟踪方案
常用的会话跟踪方案有以下两种:
1.Cookie(客户端会话技术:将数据存到客户端)
2.Session(服务器端会话技术:将数据存到服务器端)
Cookie |
下图解释了Cookie在web浏览器与web服务器之间进行交互的时候传输过程:
1. 当浏览器向web服务器端发起某个请求,第一次访问服务器端的时候,请求中是不带Cookie的,当请求到达服务器端,服务器会在响应头中附带传送给浏览器端一个小文本文件。
2. 浏览器接收到web服务器端响应的数据并解析Cookie,将Cookie保存为文件,以后每次该浏览器向web服务器发送请求的时候,都会在请求体消息中带上此Cookie信息。
3. web服务器端接收到来自浏览器的请求,并对Cookie进行解析,获取Cookie信息。
1.Cookie如何使用?
还是用撸代码表示一下:
首先创建两个项目(使用IDEA创建项目的时候勾选上Spring Web依赖)
项目一:端口8083
@Controller
@RequestMapping("/index")
public class CookieDemo1 {
@RequestMapping("/addCookie")
public void addCookie(HttpServletResponse response){
//1.创建Cookie
Cookie cookie = new Cookie("name", "良民");
//2.发送Cookie
response.addCookie(cookie);
}
}
项目二:端口8084
@Controller
@RequestMapping("/index")
public class getCookie {
@RequestMapping("/getCookie")
public void getCookie(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
System.out.println("Cookie的名称:" + cookie.getName() +"|||||"+ "Cookie的值:" + cookie.getValue());
}
}
}
}
1.现在先访问一下8084端口项目:
发现request中没有Cookie信息。
2.再访问一下8083端口:
发现Cookie被写到response响应信息中
3.再次访问8084端口:
从request中发现了Cookie信息。
从这里也印证了前面Cookie传输过程图
。
2.Cookie存活时间?
1. 如果没有设置Cookie的过期时间,则默认是浏览器关闭的时候,Cookie消失。此种Cookie的生命周期就是浏览器会话期间,也叫会话Cookie,会话Cookie一般存在内存上而不是硬盘上。
2. 如果设置了Cookie存活时间,则浏览器会将此Cookie存放到硬盘上,关闭浏览器之后再打开浏览器,如果此Cookie没有被手动清除并且没有到过期时间,则此Cookie依然有效。
设置Cookie存活时间:
cookie.setMaxAge(存活多少秒)
当cookie.setMaxAge()
设置为0时,会在浏览器上马上删除指定的cookie。
当cookie.setMaxAge()
设置为-1时,代表关闭当前浏览器Cookie即失效。
注意:Cookie是存放在客户端上的
3.同Tomcat服务器下不同项目Cookie共享?
假如在一个Tomcat服务器中部署了多个web项目,那么在默认的情况下,这些web项目中的Cookie信息是不能够共享的。
cookie.setPath()
方法可以指定cookie的取值范围,也就是说调用了该方法指定了路径之后,那么该路径下的所有资源均可共享Cookie信息。
如果我们想多个项目之间共享Cookie信息,则可以调用此方法的时候,将路径设置为两个项目的路径交集部分(比如cookie.setPath("/")
)。
4.不同Tomcat服务器之间Cookie共享?
不同的Tomcat服务器之间的项目是可以共享的,借助cookie.setDomain(String pattern)
方法既可以实现。前提是不同的项目的一级域名相同
此方法的参数应该是两个项目之间共同的域名 ,比如:news.baidu.com
和map.baidu.com
两个项目之间,实现cookie共享参数为.baidu.com
;
5.Cookie特点
1. Cookie存储于客户端,也正因为存储于客户端,所以Cookie安全系数相对于存储在服务器端的Session来说较低,容易被人篡改。
2. Cookie数据有大小限制,单个Cookie最大限制为4kb。同一个域名下的Cookie数量上限为20个(浏览器存储的Cookie信息可以在浏览器的设置中查看)。
6.Cookie作用
1. Cookie一般用于存储少量不太敏感的数据。
2. 在不登录的情况下,完成服务端对客户端的身份识别。
Cookie案例 |
需求:
访问一个接口,如果是第一次访问,则返回:“您好!欢迎您首次访问!”
,如果不是第一次访问,则返回欢迎回来:”2019年10月23日-11:03:43
(时间为上次访问的时间)
@Controller
@RequestMapping("/cookieIndex")
public class CookieTest {
@RequestMapping("/queryCookie")
public void queryCookie(HttpServletRequest request, HttpServletResponse response) throws IOException {
//1.因为需求中需要response的数据中有中文,所以设置字符集
response.setContentType("text/html;charset=utf-8");
//2.获取所有cookies
Cookie[] cookies = request.getCookies();
//获取当前时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年mm月dd日-HH:mm:ss");
String date = sdf.format(new Date());
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
if ("lastTime".equals(name)) {
//3.1如果cookie中有lastTime的数据
//3.2获取该cookie对应的value值(也就是上次访问的时间)
String value = cookie.getValue();
//3.3将value值打印出来
response.getWriter().write("欢迎回来:" + value);
//3.4向cookie中放入新的访问时间
cookie.setValue(date);
//设置存活时间1小时
cookie.setMaxAge(60*60);
response.addCookie(cookie);
//3.5停止for循环
break;
}
}
} else {
//没有cookie信息
//4.打印首次访问信息
response.getWriter().write("欢迎您首次访问");
//5.new 一个新的cookie,放到响应中
Cookie cookie = new Cookie("lastTime", date);
cookie.setMaxAge(60);
response.addCookie(cookie);
}
}
}
访问地址:http://localhost:8084/cookieIndex/queryCookie
(此项目的端口号我设置为8084)
再次刷新此页面:
使用Cookie成功记住上次访问的时间。