# cookie会话技术
会话就相当于两个人之间进行聊天,一问一答,如果其中一个人离开,那么也就代表他们之间的谈话结束,在会话技术中,两人之间是代表浏览器
和服务器
之间的请求和响应,请求和响应
可以看成是一问一答的会话,如果浏览器或者服务器关闭,那么他们之家的请求和响应(谈话)也就结束了
一次会话:从他们之间建立连接开始,到其中一个断开结束
因为是请求和响应(会话)一问一答模式,所以一次会话中发生多次请求和响应发生
每个请求都是独立存在的,他们之间不能进行数据传输,请求转发不是
但是使用会话技术就可以完成,请求之间可以进行数据传输
# 会话应用
会话技术在哪些地方应用?
例如京东,当我们购物时,每一次点击添加到购物车,都是一次请求,当我们东西选够了,就到购物车进行结算,但是当我们到购物车中时,刚才添加的东西,都在购物车中,如果在会话技术中,请求之间是不能进行数据传输,(购物车结算也是一个请求),那么我们就无法知道我们选了哪些东西,更本就不会显示出来
# 方式
分为
客户端会话
: cookie
服务器端会话
:session
# Cookie
Cookie的使用非常广泛,一般用在,未登录情况下,完成系统的设置
,比如百度页面,在未登录的情况下,我们也可以完成个性化的设置,当我们点击保存的时候,就会为我们的设置生成cookie,当下一次再次打开(在设置的这个浏览器中),请求就会带着cookie
到服务器,服务器很快就可以通过这个cookie的值进行个性化的设置
# 步骤
- 创建Cookie对象,并且
绑定数据
,格式cookie名:值
,其底层应该是一个map集合存储的- 发送cookie,通过
response
- 获取cookie值,通过
request
//创建对象
Cookie cookie = new Cookie("msg","hello");
//发送cookie
response.addCookie(cookie);
//获取cookie
Cookie[] cookies = request.getCookies();
System.out.println(cookies);
for (Cookie cookie1 : cookies) {
String name = cookie1.getName();
String value = cookie1.getValue();
System.out.println(name+":"+value);
}
2
3
4
5
6
7
8
9
10
11
12
如果在发送cookie的这个文件中进行获取cookie的话,会发生500,因为还没有发送,就获取cookie,为空,尽管idea会有一个默认的cookie,但是也要在发送cookie之后才有
# cookie原理
创建
cookie对象
,并且绑定数据,键值对客户端发送请求
response
调用方法addCookie()
,将cookie发送给客户端,并在相应头中设置cookieSet-Cookie: msg=hello
客户端再次发送请求,请求会带着cookie以前发送给服务器,并且在请求头中,有一个
cookie
头的值为响应头中的Set-Cookie
值,响应头中不会有Set-Cookie
,同一个浏览器,同一段时间,如果没有设置生命周期为0的话,cookie只会出现一次在响应头中,也就是客户端第一次发送请求的时候
# 存活时间
cookie的存活时间:服务器发送cookie,浏览器再次请求,多久能够消失
默认cookie的存活时间是:关闭浏览器的时候,cookie就会被销毁,下次再次打开时,又会再一次获取,通过方法可以设置cookie的存活时间
setMaxAge(int second>0),cookie会持久化的保存在本地磁盘中,下次打开浏览器时,会从本地中取出,但是在本地存储的时间是和
second
的值有关系的,也就是在本地存放多少秒才销毁,比如
setMaxAge(30)
cookie会被保存在本地,30秒后系统会对其进行销毁
setMaxAge(int second<0)
默认情况就是这种,
setMaxAge(int second=0)
会立即对cookie进行销毁,也就是服务器才刚刚发送完cookie,浏览器就会对cookie进行删除
# cookie特点
cookie存储数据是存储在客户端浏览器中
浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个),不同浏览器的要求不同
# 作用
因为cookie值
是公开的,我们都能够查看,所以他的安全性不高
cookie一般用于存出少量的不太敏感的数据
在不登录的情况下,完成服务器对客户端的身份识别
# cookie共享问题
假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
默认情况下cookie不能共享
但是可以通过设置其路径,达到共享的效果setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
如果要共享,则可以将path设置为"/"
,因为在同一个Tomcat服务器中,不同项目之间,也就是虚拟目录不同,将path设置为"/"
代表着cookie在根路径下都是共享的,也就是在localhost
下是共享的
# 打印上次访问时间
需求
如果是首次访问,则打印欢迎,并创建cookie,并将现在时间保存在cookie里面
如果不是首次,则打印上次显示时间,并更新cookie值
package com.chu.cookie;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/servletCookieTest")
public class ServletCookieTest extends HttpServlet {
@Override
protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//记录上次打开浏览器的时间 cookie名字为lastTime
Cookie[] cookies = request.getCookies();
//1.判断是否有cookie
//2.存在cookie,获取cookie 打印上次访问时间
//3.不存在cookie 则发送cookie,并写出欢迎词,发送cookie
if (cookies != null) {
//存在cookie 遍历cookie
for (Cookie cookie : cookies) {
//获取名字
String name = cookie.getName();
//判断名字中是否存在cookie名字
if (name.contains("lastTime")) {
//cookie中包含名字
//获取值
String value = cookie.getValue();
//解码
value = URLDecoder.decode(value,"utf-8");
response.getWriter().write("你上次访问时间为: "+value);
//设置新的cookie时间
//时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = sdf.format(new Date());
//编码
format = URLEncoder.encode(format,"utf-8");
cookie.setValue(format);
cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
response.addCookie(cookie);
return;
}
}
}
if (cookies == null) {
//不存在cookie 新建cookie 发送
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = sdf.format(date);
//编码
format = URLEncoder.encode(format, "utf-8");
Cookie cookie = new Cookie("lastTime", format);
//设置cookie的存活时间
cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
response.addCookie(cookie);
response.getWriter().write("欢迎你首次访问");
}
}
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
因为cookie中不能保存中文,还有空格,所以需要将时间日期进行转码处理
//编码
String name = "水电费何老师";
name = URLEncoder.encode(name,"utf-8");
System.out.println(name);
//解码
name = URLDecoder.decode(name,"utf-8");
System.out.println(name);
/*
运行结果
%E6%B0%B4%E7%94%B5%E8%B4%B9%E4%BD%95%E8%80%81%E5%B8%88
水电费何老师
*/
2
3
4
5
6
7
8
9
10
11
12
13
设置cookie的声明周期时,如果只是在创建cookie的那个对象那里设置声明周期,会出现debug,如果不是首次,设置完cookie值后,还应该设置声明周期,最重要的还需要再次提交cookie,如果不再次提交的话,永远都是一个值,因为就只有一个会话request
# cookie数据域
cookie对于重定向也是可以的
# cookie中解决不同域名之间的跨域问题
现在有两个域名,api.vipblogs.cn,ht.vipblogs.cn实现cookie之间的跨域问题
api.vipblogs.cn/Cookie1文件下,会添加cookie,
@Override
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("ccc1","c1");
cookie.setMaxAge(100);
cookie.setPath("/");
cookie.setDomain(".vipblogs.cn");
response.addCookie(cookie);
}
2
3
4
5
6
7
8
ht.vipblogs.cn/cookie.html使用ajax的方式,点击访问api.vipblogs.cn/Cookie1
添加cookie,
<button class="but1">co1</button>
<button class="but2">co2</button>
<button class="but3">co3</button>
<script>
$(function () {
$(".but1").click(function () {
$.get({
url: "",
xhrFields: {
withCredentials: true
},
crossDomain: true,
})
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
不同域名之间的cookie共享的时候,一定要设置cookie.setDomain(".vipblogs.cn");
这里需要加上点号.
,也可以设置成cookie.setDomain("vipblogs.cn");
在tomcat8以上,就不能设置.vipblogs.cn
形式,需要更改一下,在context.xml
文件中,加上
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
<Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
</Context>
2
3
4
5
6
7
8
9
10
11
12
13
子域名可以共享父域名中的cookie,也就是vipblogs.cn中的cookie,所有的二级域名都能够得到
但是使用ajax请求添加cookie的时候,一定要加上
xhrFields: {
withCredentials: true
},
crossDomain: true,
2
3
4
因为默认ajax是不会携带cookie发送请求的





