当前位置: 首页 > 图灵资讯 > 技术篇> 揭开JavaWeb中Cookie与Session的神秘面纱

揭开JavaWeb中Cookie与Session的神秘面纱

来源:图灵教育
时间:2023-05-21 09:25:18

1.会话跟踪技术概述

  • 会话:用户打开浏览器,访问web服务器资源,建立会话,直到一方断开连接,会话结束。它可以包含在一次会话中多次请求及响应。
  • 在浏览器向前端发出请求并响应服务器数据后,建立了一个对话(在浏览器和服务器之间)
  • 会话建立后,如果浏览器或服务器没有关闭,会话将继续建立
  • 浏览器和服务器可以继续使用会话进行请求发送和响应,上述整个过程称为会话

思考:下图共建立了几个会话?

揭开JavaWeb中Cookie与Session的神秘面纱_数据

揭开JavaWeb中Cookie与Session的神秘面纱_服务器_02

为什么一个会话要求多次共享数据?有了这个数据共享功能,可以实现哪些功能?

  • 页面显示用户登录信息:许多网站在登录后访问多个功能并发送多个请求后,会有当前登录用户的信息[用户名],如百度、京东、码云等。

揭开JavaWeb中Cookie与Session的神秘面纱_数据_03

  • 网站登录页面记住我功能:当用户成功登录时,检查记住我按钮下次登录时,网站会自动填写用户名和密码,简化用户登录操作,多次登录会有多个请求,也涉及共享数据

揭开JavaWeb中Cookie与Session的神秘面纱_服务器_04

具体原因分析后,如何实现会话跟踪技术? 具体实现方法如下:

(1)客户端会话跟踪技术:Cookie

(2)服务端会话跟踪技术:Session

这两种技术都可以实现会话跟踪,它们之间最大的区别是:Cookie存储在浏览器端,Session存储在服务器端插入图片描述

二、Cookie2.1 Cookie的基本使用

1.概念

Cookie:客户端会话技术,将数据保存到客户端,然后每次请求都携带Cookie数据进行访问。

2.Cookie的工作流程

揭开JavaWeb中Cookie与Session的神秘面纱_服务器_05

3.Cookie的基本使用

对于Cookie的使用,我们应该更加关注后台代码如何操作Cookie。Cookie的操作主要分为两类,即发送Cookie获取Cookie,如何实现以上两个内容?

3.1 发送Cookie

  • 创建Cookie对象,并设置数据

 

Cookie cookie = new Cookie("key","value");

 

  • 将Cookie发送到客户端:使用response对象

 

response.addCookie(cookie);

 

揭开JavaWeb中Cookie与Session的神秘面纱_数据_06

3.2 获取Cookie

  • 使用客户端携带的所有Cookierequest对象

 

Cookie[] cookies = request.getCookies();

 

  • 获得每一个Cookie对象的遍历数组:for
  • 使用Cookie对象获取数据

 

cookie.getName();cookie.getValue();

 

2.2 Cookie的原理分析

Cookie的实现原理是基于HTTP协议,其中设计了HTTP协议中的两个请求头信息:

  • 响应头:set-cookie
  • 请求头: cookie

揭开JavaWeb中Cookie与Session的神秘面纱_服务端_07

  • 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[]后,可以从中获取所需的数据
2.3 使用Cookie的细节

在本节中,我们主要讲解两个知识,一是Cookie的生存时间,二是Cookie如何存储中文。首先,让我们学习Cookie的生存时间。

2.3.1 Cookie的存活时间

揭开JavaWeb中Cookie与Session的神秘面纱_数据_08

如果BServlet在将请求发送到BServlet之前关闭浏览器并打开访问,BServlet能否获取Cookie数据?

  • 在默认情况下,Cookie存储在浏览器内存中,当浏览器关闭并释放内存时,Cookie将被销毁

这一结论证实了上述演示效果,但如果使用这种默认情况下的Cookie,则无法实现一些需求,例如:

揭开JavaWeb中Cookie与Session的神秘面纱_服务端_09

这个网站的登录页面上有一个记住我大家都熟悉这个功能。

所以我们现在遇到的一个问题是如何持久存储Cookie。

其实Cookie已经为我们提供了相应的API来完成这件事,这个API就是setMaxAge,

  • 设置Cookie存活时间

 

setMaxAge(int seconds)

 

参数值为:

1.正数:将Cookie写入浏览器所在电脑的硬盘,并持续存储。到时间自动删除

2.负数:默认值,当浏览器关闭时,Cookie在当前浏览器内存中被销毁

3.零:删除相应的Cookie

揭开JavaWeb中Cookie与Session的神秘面纱_数据_10

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中使用。

揭开JavaWeb中Cookie与Session的神秘面纱_数据_11

3,Session

Cookie已经完成了一次会话和多个请求之间的数据共享,我们之前也提到过Session也可以实现,所以:

3.1 Sesssion的基本使用

1.概念

Session:服务端会话跟踪技术:将数据保存到服务端。

  • Session存储在服务端,Cookie存储在客户端
  • 存储在客户端的数据容易被盗和拦截,存在许多不安全因素
  • 与客户端相比,存储在服务端的数据更安全

2.Sesssion的工作流程

揭开JavaWeb中Cookie与Session的神秘面纱_服务器_12

  • 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)前提条件

揭开JavaWeb中Cookie与Session的神秘面纱_服务器_13

Session要想实现一次会话多次请求之间的数据共享,必须保证多次请求获取Session的对象是一样的。

所以最重要的问题来了,Session是如何保证Session在一次会话中获得的对象是一样的?

揭开JavaWeb中Cookie与Session的神秘面纱_数据_14

(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实现的
3.3 Sesssion使用细节

本节将主要讲解两个知识,一是Session的钝化和激活,二是Session的销毁。首先,我们来学习什么是Session的钝化和激活。

3.3.1 Sesssion钝化和活化

首先要考虑的问题是:

  • Session中的数据在服务器重启后还在吗?

要回答这个问题,我们可以先看下图,

揭开JavawebCookie和Session的神秘面纱_服务端_15'

(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存储在客户端,可以长期保存
3.3.2 Session销毁

销毁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用于保存用户登录后的数据