• 会话管理 : Cookie和Session



    提示:以下是本篇文章正文内容,Java系列学习将会持续更新

    一、什么是 Cookie和Session?

    HTTP 协议的请求默认是 “无状态” 的。

    “无状态” :
    默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系.
    但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
    例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了.

    所以为了记录客户端和服务器的通信状态,就有了 会话管理 机制。
    cookie : 会员卡 / 令牌。cookie 机制是通过检查客户身上的“通行证”来确定客户身份。
    session : 制作 / 颁发令牌。session 机制就是通过检查服务器上的“客户明细表”来确认客户身份。session 相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

    在这里插入图片描述
    回到目录…

    二、会话机制

    • 每个浏览器中的Session是不一样的,当你在A浏览器中请求到一个session,但是到了B浏览器中是没有Session的。
    • 默认Session是存储在内存中的,不会持久化保存。

    2-1 手动新建 session

    @WebServlet("/first-visit")
    public class FirstVisitServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 第一次访问,需要办会员卡(cookie)+ 准备专属的文件柜(session)
            // 这个 session 对象就是你的专属服务柜
            HttpSession session = req.getSession(true); // true表示如果没有会员卡,就给你办理
            // 手动添加内容 (会话日期)
            session.setAttribute("first-visit-at", new Date());
    
            resp.setCharacterEncoding("utf-8");
            resp.setContentType("text/plain");
            resp.getWriter().println("办理会员成功");
    
            // 1. 直接访问其他 URL,观察 请求中有没有 Cookie 头、观察应用/Cookie 有没有值
            // 2. 访问  /first-visit,观察响应头中的 Set-Cookie
            // 3. 再次访问其他 URL,观察 请求中有没有 Cookie 头、观察应用/Cookie 有没有值
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    观察现象:

    1. 直接访问其他 URL,观察请求中有没有 Cookie 头、观察应用/Cookie 有没有值
    2. 首次访问 /first-visit,观察响应头中的 Set-Cookie
    3. 再次访问/first-visit,观察 请求头中的 Cookie 头、观察应用中的Cookie值

    回到目录…

    2-2 查看session创建时间

    @WebServlet("/get-first-time")
    public class GetFirstTimeServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setCharacterEncoding("utf-8");
            resp.setContentType("text/plain");
            PrintWriter writer = resp.getWriter();
    
            HttpSession session = req.getSession(false); // 保证不新建会员柜
            if (session == null) {
                writer.println("没有专属文件柜,不是会员");
                return;
            }
    
            Object o = session.getAttribute("first-visit-at");
            if (o == null) {
                writer.println("文件柜有,但纸上没有记录内容");
            }else{
                Date date = (Date) o;
                writer.println(date);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    回到目录…

    2-3 HTTPSession 的常见方法

    Session的结构: 在这里插入图片描述

    1. 每个会员有一个专属的文件柜,并不是所有会员共用一个柜子
      Map
    2. 每个 HTTPSession对象中存储了若干条信息 (key-value)
      Map

    HTTPSession对象的常见方法:

    getAttribute(name); // 根据name获取value, 如果没有则null
    setAttribute(name, value); // 插入/更新name-value
    removeAttribute(name); // 删除name-value
    
    • 1
    • 2
    • 3

    回到目录…

    三、Cookie 和 Session 分离使用

    • Cookie和Session虽然最常见的场景是一起配合工作的,但其实两者是独立的。
    • Cookie离开Session 可以独立使用;
    • Session离开Cookie 也可以独立使用;

    3-1 单独添加 Cookie

    @WebServlet("/only-set-cookie")
    public class OnlySetCookieServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Cookie cookie1 = new Cookie("name", "wangshaoyu");
            // 设置过期时间 (默认为当前进程)
            cookie1.setMaxAge(120);
            resp.addCookie(cookie1);
    
            Cookie cookie2 = new Cookie("gender", "male");
            resp.addCookie(cookie2);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3-2 查看 Cookie

    @WebServlet("/only-get-cookie")
    public class OnlyGetCookieServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Cookie[] cookies = req.getCookies();
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName() + " => " + cookie.getValue());
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    回到目录…

    四、总结

    4-1 cookie+session是干嘛的?

    1. 用于会话管理
      (默认的HTTP协议是无状态的 : 服务器不知道访问的请求属于哪个会话)
      一个会话可能会有若干个请求

    2. Cookie 是客户端(Client)和服务器(Server)之间的通信,是HTTP协议相关的

      • 浏览器 : ①保存好Cookie; ②需要在之后的请求中携带Cookie
      • 服务器 : 生成Cookie 并传递给浏览器
      • 表现在HTTP协议上:
        请求头: Cookie: name 1=value1; name2=value2
        响应头: Set-Cookie: namel=valuel; name2=value2
      • Cookie 可以独立使用 : 过期时间、域名、路径…
    3. Session 是服务器(Server) 内部的一套数据流程

      • Session默认存储于内存中,但实际上不做限制,哪里都可以存储
      • 通过session-id取到的数据,我们的代码中看到的还是Map < String, Object>
      • 只要session存储,我们可以跨请求共享数据
      • Session可以独立工作
    4. 使用Cookie + Session解决会话管理时,Cookie 的主要职责是携带session-id

    5. 通常session cookie是不能跨窗口使用的,每个浏览器的session都不一样

    6. Cookie和Session最主要的功能是用于做登录态管理的
      判断用户是否已经登录

    回到目录…

    4-2 cookie和session的区别

    1. 相同点
      它们都由服务器创造。
      服务器依赖Cookie来传递SessionID值,也可以通过URL重写的方式来传递SessionID的值。

    2. 存在的位置不同:
      cookie 存在于浏览器,临时文件夹中;
      session 存在于服务器的内存中,一个 session 域对象为一个用户浏览器服务。

    3. 安全性不同:
      cookie 是以明文的方式存放在客户端的,安全性低,可以通过一个加密算法进行加密后存放;
      session 存放于服务器的内存中,所以安全性好。

    4. 存储的数据类型不同:两者都是key-value结构,但针对value的类型是有差异的。Cookie:value只能是字符串类型,session:value是object类型。

    5. 存储的数据大小限制不同:cookie大小受浏览器的限制,很多是4k的大小,session理论受内存的限制。

    6. 生命周期的控制
      关闭浏览器,只会是浏览器端内存里的session cookie消失;但不会使保存在服务器端的session对象消失。
      cookie的生命周期是累计的,从创建时就开始计时,30min后cookie生命周期结束
      session的生命周期是间隔的,从创建时开始计时如在30min内没有访问session,那么session生命周期就被销毁

    回到目录…


    总结:
    提示:这里对文章进行总结:
    以上就是今天的学习内容,本文是JavaWeb的学习,学习了HTTP的会话管理机制,区分了CookIe和Session各自的职责。之后的学习内容将持续更新!!!

  • 相关阅读:
    【luogu AT2366】Prefix Median(DP)
    【docker专栏3】docker基础概念-容器、镜像以及引擎组成部分
    go 视频解码 -- 笔记
    程序员的爱恨交织与双标态度
    CentOS8下面RabbitMQ的安装
    Java版Http请求post和get两种调用实现
    【Mybatis小白从0到90%精讲】12:Mybatis删除 delete, 推荐使用主键删除!
    智能算法 | MATLAB实现SA模拟退火算法函数寻优
    /usr/lib/x86_64-linux-gnu/libQt5Core.so.5: version `Qt_5.15‘ not found
    测试ForOf会不会多次调用函数2208082050
  • 原文地址:https://blog.csdn.net/qq15035899256/article/details/126371953