1.会话跟踪技术概述
- 会话:用户打开浏览器,访问web服务器资源,建立会话,直到一方断开连接,会话结束。它可以包含在一次会话中多次请求及响应。
- 在浏览器向前端发出请求并响应服务器数据后,建立了一个对话(在浏览器和服务器之间)
- 会话建立后,如果浏览器或服务器没有关闭,会话将继续建立
- 浏览器和服务器可以继续使用会话进行请求发送和响应,上述整个过程称为会话。
思考:下图共建立了几个会话?
为什么一个会话要求多次共享数据?有了这个数据共享功能,可以实现哪些功能?
- 页面显示用户登录信息:许多网站在登录后访问多个功能并发送多个请求后,会有当前登录用户的信息[用户名],如百度、京东、码云等。
- 网站登录页面
记住我
功能:当用户成功登录时,检查记住我
按钮下次登录时,网站会自动填写用户名和密码,简化用户登录操作,多次登录会有多个请求,也涉及共享数据
具体原因分析后,如何实现会话跟踪技术? 具体实现方法如下:
(1)客户端会话跟踪技术:Cookie
(2)服务端会话跟踪技术:Session
这两种技术都可以实现会话跟踪,它们之间最大的区别是:Cookie存储在浏览器端,Session存储在服务器端插入图片描述
二、Cookie2.1 Cookie的基本使用1.概念
Cookie:客户端会话技术,将数据保存到客户端,然后每次请求都携带Cookie数据进行访问。
2.Cookie的工作流程
3.Cookie的基本使用
对于Cookie的使用,我们应该更加关注后台代码如何操作Cookie。Cookie的操作主要分为两类,即发送Cookie和获取Cookie,如何实现以上两个内容?
3.1 发送Cookie
- 创建Cookie对象,并设置数据
Cookie cookie = new Cookie("key","value");
- 将Cookie发送到客户端:使用response对象
response.addCookie(cookie);
3.2 获取Cookie
- 使用客户端携带的所有Cookierequest对象
Cookie[] cookies = request.getCookies();
- 获得每一个Cookie对象的遍历数组:for
- 使用Cookie对象获取数据
cookie.getName();cookie.getValue();
2.2 Cookie的原理分析
Cookie的实现原理是基于HTTP协议,其中设计了HTTP协议中的两个请求头信息:
- 响应头:set-cookie
- 请求头: cookie
- AServlet发送到前端Cookie,bservlet从request中获取Cookie的功能
- 当Tomcat发现后端要返回的是Cookie对象时,Tomcat会在响应头中添加一行数据==
Set-Cookie:username=zs
== - 浏览器获得响应结果后,可以从响应头中获得
Set-Cookie
对应值username=zs
,并将数据存储在浏览器内存中 - 当浏览器再次向BServlet发送请求时,浏览器会自动向请求头添加请求==
Cookie: username=zs
==发送给服务器BServletet - Request对象将要求头中cookie对应的值封装成cookie对象,最终形成数组
- BServlet通过Request对象获取Cokie[]后,可以从中获取所需的数据
在本节中,我们主要讲解两个知识,一是Cookie的生存时间,二是Cookie如何存储中文。首先,让我们学习Cookie的生存时间。
2.3.1 Cookie的存活时间如果BServlet在将请求发送到BServlet之前关闭浏览器并打开访问,BServlet能否获取Cookie数据?
- 在默认情况下,Cookie存储在浏览器内存中,当浏览器关闭并释放内存时,Cookie将被销毁
这一结论证实了上述演示效果,但如果使用这种默认情况下的Cookie,则无法实现一些需求,例如:
这个网站的登录页面上有一个记住我
大家都熟悉这个功能。
所以我们现在遇到的一个问题是如何持久存储Cookie。
其实Cookie已经为我们提供了相应的API来完成这件事,这个API就是setMaxAge,
- 设置Cookie存活时间
setMaxAge(int seconds)
参数值为:
1.正数:将Cookie写入浏览器所在电脑的硬盘,并持续存储。到时间自动删除
2.负数:默认值,当浏览器关闭时,Cookie在当前浏览器内存中被销毁
3.零:删除相应的Cookie
2.3.2 Cookie存储中文- Cookie不能直接存储中文
Cookie不能存储中文,但如果有这方面的需求,这个时候该怎么解决呢?
在这个时候,我们可以使用我们以前学到的一个知识点URL编码
,因此,如果需要存储中文,则需要进行转码。具体实现思路如下:
1.在AServlet中用URL编码中文,使用URLEncoder.encode(),将编码值存储在Cookie中
2.在BServlet中获得Cookie中的值,获得URL编码后的值
3.用URLDecoder解码获得的值.decode(),可获得相应的中文值
(1)在AServlet中用URL编码中文
@WebServlet("/aServlet")public class AServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ///发送Cookie String value = “黑洞小威”; ////用URL编码中文 value = URLEncoder.encode(value, "UTF-8"); System.out.println(”存储数据:"+value); ////将编码值存储在Cookie中 Cookie cookie = new Cookie("username",value); //设置存活时间 ,1周 7天 cookie.setMaxAge(60*60*24*7); //2. 发送Cookie,response response.addCookie(cookie); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); }}
(2)在BServlet中获取值并解码值
@WebServlet("/bServlet")public class BServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得Cookie //1. 获得Cookie数组 Cookie[] cookies = request.getCookies(); //2. 遍历数组 for (Cookie cookie : cookies) { //3. 获取数据 String name = cookie.getName(); if("username".equals(name)){ String value = cookie.getValue();///获得URL编码后的值 %E5%BC%A0%E4%B8% ///URL解码 value = URLDecoder.decode(value,"UTF-8"); System.out.println(name+":"+value);///value解码后 黑洞晓威 break; } } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); }}
到目前为止,我们可以将中文存储在Cookie中使用。
3,SessionCookie已经完成了一次会话和多个请求之间的数据共享,我们之前也提到过Session也可以实现,所以:
3.1 Sesssion的基本使用1.概念
Session:服务端会话跟踪技术:将数据保存到服务端。
- Session存储在服务端,Cookie存储在客户端
- 存储在客户端的数据容易被盗和拦截,存在许多不安全因素
- 与客户端相比,存储在服务端的数据更安全
2.Sesssion的工作流程
- AServlet在服务端获取Session对象,并将数据存储在其中
- BServlet在服务端获取相同的Session对象,从中取出数据
- 一次会话中多个请求之间的数据共享可以实现
- 现在最大的问题是如何确保AServlet和BServlet使用相同的Session对象(在原理分析中解释)
3.Sesssion的基本使用
- Sesssion的获取
HttpSession session = request.getSession();
- Session常用方法的使用
void setAttribute(String name, Object o)Object getAttribute(String name)
注意: Object类型的数据可以存储在Session中,也就是说,任何数据类型都可以存储在Session中。
在介绍了Session的基本使用后,Session的底层是如何实现一次会话和两次请求之间的数据共享的?
3.2 Sesssion的原理分析- Session是基于Cookie实现的
事实上,这句话并不能详细说明Session的底层实现。接下来,让我们逐步分析Session的具体实现原理:
(1)前提条件
Session要想实现一次会话多次请求之间的数据共享,必须保证多次请求获取Session的对象是一样的。
所以最重要的问题来了,Session是如何保证Session在一次会话中获得的对象是一样的?
(1)当demo1第一次获得session对象时,session对象会有一个唯一的标志,如果是的话id:10
(2)demo1在session中存储其他数据并处理所有业务后,需要通过tomcat服务器响应浏览器
(3)Tomcat服务器发现session对象用于业务处理,session的唯一标志将被识别id:10
添加作为cookie,Set-Cookie:JESSIONID=10
在响应头中响应浏览器
(4)浏览器收到响应结果后,会将响应头中的coookie数据存储在浏览器的内存中
(5)当浏览器在同一会话中访问demo2时,cookie中的数据将按照cookie: JESSIONID=10
将格式添加到请求头并发送到服务器Tomcatat
(6)demo2获得请求后,从请求头读取cookie中的JSESIONID值为10,然后在服务器内存中搜索id:10
如果找到session对象,直接返回对象。如果没有,创建新的session对象。
(7)关闭并打开浏览器后,由于浏览器的cookie已经被销毁,因此没有JESSIONID数据。服务器获得的session是一个新的session对象
小结
在介绍了Session的原理之后,我们只需要记住
- Session是基于Cookie实现的
本节将主要讲解两个知识,一是Session的钝化和激活,二是Session的销毁。首先,我们来学习什么是Session的钝化和激活。
3.3.1 Sesssion钝化和活化首先要考虑的问题是:
- Session中的数据在服务器重启后还在吗?
要回答这个问题,我们可以先看下图,
(1)服务器端AServlet和BServlet共用的session对象应存储在服务器的内存中
(2)服务器重启后,内存中的数据应该已经释放,对象也应该被销毁
所以session数据应该已经不存在了
那么Tomcat服务器重启时,session数据是如何保存的呢?
具体原因是:Session的钝化和激活:
- 钝化:服务器正常关闭后,Tomcat将Session数据自动写入硬盘文件
- 钝化的数据路径如下:
项目目录\target\tomcat\work\Tomcat\localhost项目名称\项目名称SESSIONS.ser
- 激活:再次启动服务器后,将数据从文件中加载到Session
- 在Session中加载数据后,路径中的数据
SESSIONS.ser
删除文件
我们只需要了解上述整个过程。因为所有的过程都是由Tomcat自己完成的,所以我们不需要参与。
小结
介绍Session的钝化和活化后,需要注意的是:
- session数据存储在服务端,服务器重启后,session数据将被保存
- 浏览器关闭启动后,重建的连接已经是一个全新的会话,获取的session数据也是一个新的对象
- 要共享session的数据,浏览器无法关闭,因此session的数据无法长期保存
- cookie存储在客户端,可以长期保存
销毁session有两种方式:
- 默认情况下,无操作,30分钟内自动销毁
- 该故障时间可通过配置进行修改
- web在项目中.xml配置
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <session-config> <session-timeout>100</session-timeout> </session-config></web-app>
- 如果没有配置,默认值为30分钟,默认值为Tomcatweb.写在xml配置文件中的xml
- Invalidate()调用Session对象进行销毁
- 将sesssion销毁方法添加到Sessiondemo2类中
@WebServlet(/demo2)public class Sessiondemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取数据,从session中 //1. 获得Session对象 HttpSession session = request.getSession(); System.out.println(session); // 销毁 session.invalidate(); //2. 获取数据 Object username = session.getAttribute("username"); System.out.println(username); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); }}
- 启动访问测试,首先访问demo1将数据存储到session中,然后从session中访问demo2获取数据
- 当用户退出时,销毁方法通常需要销毁session。
cookie和Session总结
- Cookie 和 Session 都是来完成一次会话中多次请求的。数据共享的。
把两个对象放在一起需要思考:
Cookie和Session有什么区别?
Cookie和Session的应用场景是什么?
- 区别:
- 存储位置:Cookie 将数据存储在客户端,Session 在服务端存储数据
- 安全:Cookie不安全,Session安全
- 数据大小:Cookie最大3KB,Session没有大小限制
- 存储时间:Cookie可通过setMaxage()长期存储,Session默认30分钟
- 服务器性能:Cookie不占用服务器资源,Session占用服务器资源
- 结论
- Cookie用于确保用户在未登录的情况下识别身份
- Session用于保存用户登录后的数据