今天我们了解两个会话技术
1.cookie技术
2.session技术
会话技术
1.会话:一次会话中包含多次请求和响应
2.一次会话:浏览器第一次给服务器资源发送请求开始,会话建立,直到有一方断开为止,(浏览器或者是服务器)
3.功能:共享数据,在一次会话的范围内的多次请求间,共享数据
4.方式:(其他语言中可能也存在会话技术,但是不一定是这么取名字)
1.客户端会话技术cookie (把数据存放在客户端浏览器中)
2.服务器端会话技术 session(把数据存放在服务器端)
cookie会话技术
1.概念:客户端会话技术将数据保存在客户端
2.原理:cookie是基于请求头cookie和响应头set-cookie的实现
图解:

- 1.快速入门
1.创建cookie对象,设置数据
Cookie cookie =new Cookie("username","xzw");
2.发送cookie对象
response.addCookie(cookie);
3.获取cookie对象数组
Cookie[] cookies = request.getCookies();
//demo1
@WebServlet("/cookieServletDemo1")
public class CookieServletDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建cookie
Cookie cookie =new Cookie("username","xzw");
//2.发送cookie
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
//demo2
@WebServlet("/cookieServletDemo2")
public class CookieServletDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//3.获取Cookie,拿到里面的数据
Cookie[] cookies = request.getCookies();
if (cookies!=null){
for (Cookie c : cookies) {
String name = c.getName();
String value = c.getValue();
System.out.println(name+":"+value);
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
抓包:
-
在第一次请求响应时,请求体中没有内容,而在响应体中有set-cookie
第一次请求/响应 -
在下一次请求的时候,请求体中cookie中有cookie存储的内容,而在响应体中没有内容
在下一次请求/响应中 - 总结:就是通过响应头和请求头实现了cookie中多次请求之间共享数据
- 2.cookie会话技术中的细节和API
1.一次可以发多个cookie,创建多个cookie对象,使用reponse对象进行发送
方法:
response.addCookie(Cookie cookie);
@WebServlet("/cookieServletDemo3")
public class CookieServletDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建对个Cookie对象
Cookie cookie1 = new Cookie("mag1","1");
Cookie cookie2 = new Cookie("mag2","3");
//使用response对象对其进行发送
response.addCookie(cookie1);
response.addCookie(cookie2);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
在demo中获取可以获取两个值

思考:使用相同的cookie名字,是创建一个新的cookie还是覆盖?
答案是会覆盖
/**
* 发送多个Cookie对象
*/
@WebServlet("/cookieServletDemo3")
public class CookieServletDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建对个Cookie对象
Cookie cookie1 = new Cookie("mag1","1");
Cookie cookie2 = new Cookie("mag1","3");
//使用response对象对其进行发送
response.addCookie(cookie1);
response.addCookie(cookie2);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

2.cookie在浏览器中能保存多长时间
1,默认情况下,浏览器关闭的时候,cookie数据会被销毁(存储在浏览器的内存中)
2,我们可以设置cookie的生命周期,让cookie持久化存储(储存在硬盘中)
方法:
setMaxAge(int seconds);//参数是秒
方法参数:
1.正数,将cookie数据写在磁盘中(持久化),参数是持久化时间,以秒为单位
2.负数,默认值(浏览器关闭之后,cookie数据就会消失)
3.0,删除cookie数据
我们可以通过这个函数来设置cookie的存活时间
默认关闭浏览器之后就会消失
@WebServlet("/cookieServletDemo4")
public class CookieServletDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建一个cookie对象并绑定数据
Cookie cookie = new Cookie("time","12");
//1.1设置cookie在浏览器中的保存时间
//cookie.setMaxAge(-1);//默认关闭浏览器就会消除
// cookie.setMaxAge(300);//将cookie数据持久化纯真,300秒后删除
cookie.setMaxAge(0);//直接删除cookie信息
//2.发送数据到客户端
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
3.cookie能不能存放中文字符呢?
在tomcat8以前是无法存放中文字符的
解决方法是:需要将中文数据进行URL编解码
在tomcat8之后可以存放中文字但是无法存放特殊字符
!我们以后再做项目的时候可能由于很多原因不会使用tomcat8以上的版本,我们这个时候可以对其进行URL编解码操作
方法:
编码:
URLEecoder.encode("字符串","字符编码");
解码
URLDecoder.decode("字符串","字符编码")
用tomcat8以上的版本存放空格时,会出错
编码:
@WebServlet("/cookieServletDemo5")
public class CookieServletDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建cookie对象并绑定数据
Cookie cookie = new Cookie("msg","谢子威真的傻逼 哈哈");
//发送cookie数据到服务器
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
错误信息:

这个时候我们需要对其进行URL编解码操作
如:
/**
* 使用cookie存储中文数据,或者是特殊字符的时候
*/
@WebServlet("/cookieServletDemo5")
public class CookieServletDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String str ="谢子威真的傻逼 哈哈";
System.out.println("编码前"+str);
//进行URL编码
str = URLEncoder.encode(str, "utf-8");
System.out.println("编码后"+str);
//创建cookie对象并绑定数据
Cookie cookie = new Cookie("msgss",str);
//发送cookie数据到服务器
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
这样就可以获取正确的结果

4.cookie的共享问题
1,假设在一个tomcat服务器中部署了多个项目,那么这些项目能否共享Cookie数据?
答案,默认情况下是不可以的,但是我们可以通过方法去修改cookie的范围
在官方文档中的解释是,为客户端应该返回的cookie指定一个路径。
真正的含义就是指定cookie的作用范围,默认情况下是当前项目的虚拟路劲,所以默认情况下是不在多个项目中共享的。
如果要共享,可以将Path参数设置成"/"(代表当前目录的根目录),这样的话cookie信息就会对服务器中的所有项目共享了
方法:
cookie.setPath(String path)
案例:
/**项目一中
* 存储Cookie值,在其余的项目中观察是否能够获取
*/
@WebServlet("/cookieServletDemo6")
public class CookieServletDemo6 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建cookie对象,绑定数据
Cookie cookie = new Cookie("massage","Idea22");
//设置cookie数据在同一个tomcat下不同项目之间的作用范文
cookie.setPath("/");
//发送cookie数据到客户端
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
/**项目二
* 获取上一个项目中发送给浏览器的cookie值
*/
@WebServlet("/cookieServletTest")
public class CookieServletTest extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取所有的cookie信息
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
String name = c.getName();
String value = c.getValue();
System.out.println(name+":"+value);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
获取成功,这默认情况下,也就是说不指定的情况下是没有这个效果的

2,在不同的tomcat服务器之下,cookie数据能否共享?
答案,也是可以的,但是我们要设置不同的服务器的一级域名是相同的,那么多个服务器之间的cookie是可以共享的
方法:参数path是域名
cookie.setDomain(String path)
如在百度中,百度贴吧,和百度新闻两个服务器之间如果想要共享cookie数据可以这么写
cookie.setDomain(".baidu.com");
这么写之后,tieba.baidu.com和news.baidu.com之间可以共享到cookie数据
这个我们以后再项目中会遇到。我们在去了解,我们看看官方文档怎么解释这一个方法
官方解释:指定应该在其中显示此cookie的域。
- 3.cookie会话技术的特点
1,cookie将数据存放在客户端浏览器
2,浏览器对单个cookie的大小有限制(一般是4k),以及同一个域名下的中cookie数量有限制(一般是20个)
相对不安全,不能存放大量数据,并且只能存储String数据
作用:
1.cookie一般用于存储少量不太敏感的数据
2.在不登录的情况下,完成服务器对客户端的身份识别(很常用)
如:保存我当前没有登录的情况下,对页面的一些设置,我下次在访问的时候,服务器会在通过存放的cookie来设置我页面的设置
session会话技术
1.概念:服务器端会话技术,将数据保存在服务器端
在一个会话的多次请求间共享数据,将数据保存在服务器端
2.原理:session的实现依赖于cookie
图解:

- 1.快速入门
1,获取Session对象,我们实际上使用的是HttpSession对象,它是一个域对象
HttpSession session = request.getSession();
2,使用HttpSession对象,使用域对象的常规方法
//1.通过指定的名称获取对应的值
object getAttribute(String name);
//2.存储指定值
void setAttribute(String name ,object value);
//3.删除指定Session对象
void removeAttribute(String name);
代码演示:
//demo1
@WebServlet("/httpSessionDemo1")
public class HttpSessionDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建session对象
HttpSession session = request.getSession();
//2.将数据存储在session域对象之中
session.setAttribute("username","xzw");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
//demo2
@WebServlet("/httpSessionDemo2")
public class HttpSessionDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建Session对象
HttpSession session = request.getSession();
//2.获取Session对象中的username值
String username = (String) session.getAttribute("username");
System.out.println(username);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

抓包:
第一次的响应体中set-cookie响应头信息,携带着set-cookie:JSESSION=ID属性值的信息

下一次的请求头中Cookie头携带着Cookie:JSESSION=ID属性值的信息

注意观察这两个属性ID值是一样的,这就是在原理中,实现所有的资源创建的Session对象都是同一个对象的原因
-
2.Session域对象使用细节
1.当客户端浏览器关闭,服务器不关闭,两次获取的Session对象是不是同一个?
答案:很显然,默认情况下不是的,这都不是一个会话之间的请求,但是我们可以使用编程的方法,让他们是相同的
方法:我们通过原理可知,我们让所有获取的session对象相同的方法是通过cookie实现的,那么我们可以使用cookie持久化的方法让Session对象获取
相同
编程思想:
1.创建Cookie对象,设置他的键值对为JSESSION和对应的ID属性值
2.设置Cookie的最大存活时间,让cookie吃持久化保存
//demo3
@WebServlet("/httpSessionDemo3")
public class HttpSessionDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建Session对象
HttpSession session = request.getSession();
//2.创建Cookie对象
Cookie cookie = new Cookie("JSESSION",session.getId());
//3.设置cookie对象的最大存活时间
cookie.setMaxAge(60*10);
//4.打印Session的id属性值
System.out.println("demo3:"+session.getId());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
//demo4
@WebServlet("/httpSessionDemo4")
public class HttpSessionDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建Session对象
HttpSession session = request.getSession();
//2.打印Session对象的ID属性
System.out.println("demo4:"+session.getId());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
关闭浏览器之后访问,可以获取相同的Session对象,说明这种方法可以在浏览器关闭之后获取同一个Session对象,可以获取Session对象中的数据
控制台:

2.客户端不关闭,但是服务器端关闭,两次获取的Session对象是同一个吗?
答案:当然不是同一个,在服务器关闭之后Session对象会销毁,再次创建的Session对象和以前的肯定是不同的,但是要是这样的话,我们的项目就会出现很多问题,所以我们要确保数据不丢失,我们是怎么解决这个问题的呢?
虽然对象不是同一个,但是我们可以确保数据是同一个
解决方法
Session对象的钝化:在服务器关闭之前,将Session对象序列化到硬盘。
Session对象的活化:在服务器启动之后,将Session文件转化成内存中的Session对象即可。
Tomcat服务器自动为我们把这件事给做了,但是IDEA并不能完成这件事,IDEA可以钝化,但是活化不成功,但是无所谓,将来我们配置项目都是配置在Tomcat服务器之中
3.Session的失效时间(Session对象什么时候被销毁)?
1,服务器关闭
2,Session对象调用invalidate();对象销毁自己
3,Session对象的默认失效时间是30分钟,在tomcat服务器的web.xml文件中,可以更改失效时间。当然要是项目使用XML配置也可以使用web.xml对其配置
在web.xml中如图:


-
3.Session会话技术的特点
1.Session用于存储一次会话的多次请求的数据,存储在服务器端
2.Session可以存储任意类型任意大小的数据
相对安全,可以存放大量数据,不用考虑数据的类型
例如:在重定向中,由于是多次请求,我们可以考虑采用Session个Application Context 存放数据,但是我们一般存放在Session对象中,因为Application Context对象的作用域太大了,Session在会话域中使用的十分广泛
cookie和session的区别:
1,session数据存档在服务器端,而cookie在客户端
2,session没有大小限制,但是cookie有
3,session的数据相对安全,cookie相对不安全

