【JavaWeb】会话管理 cookie session 三大域对象总结

文章目录

  • 会话管理
  • 一、Cookie
    • 1.1 Cookie的使用
    • 1.2 Cookie的时效性
    • 1.3 Cookie的提交路径
  • 二、Session
    • 2.1 HttpSession的使用
    • 2.2 HttpSession时效性
  • 三、三大域对象
    • 3.1 域对象概述
    • 3.2 域对象的使用
  • 总结


会话管理

HTTP是无状态协议

  • 无状态就是不保存状态,即无状态协议(stateless)
  • HTTP协议自身不对请求和响应之间的通信状态进行保存
  • 发送请求和接受响应不做持久化处理

无状态 每次都要重新输入
有状态 按照上次的直接显示 不用再输入一次

实现会话管理的方式:

Cookie和Session配合解决

  • cookie是在客户端保留少量数据的技术
    • 主要通过响应头向客户端响应一些客户端要保留的信息
  • session是在服务端保留更多数据的技术,
    • 主要通过HttpSession对象保存一些和客户端相关的信息
  • cookie和session配合记录请求状态

举例:

  • 第一次输入登录信息 发送给服务器后 将信息存储到session中,返回响应给了一个cookie;
  • 下一次登录时候,浏览器发送cookie 从服务器存储的session中拿到上一次的登录信息 来使用
  • 也就是:在名为session的保险库里存放信息后,会给一个cookie是用于取出信息的凭证。(黑客帝国)

一、Cookie

cookie是一种客户端会话技术cookie服务端产生,服务器存放在浏览器的一小份数据,浏览器以后每次访问该服务器的时候都会将这小份数据携带到服务器去。

  • 服务端创建cookie,将cookie放入响应对象中,Tomcat容器将cookie转化为set-cookie响应头,响应给客户端
  • 客户端在收到cookie的响应头时,在下次请求该服务的资源时,会以cookie请求头的形式携带之前收到的Cookie
  • cookie是一种键值对格式的数据,从tomcat8.5开始可以保存中文,但是不推荐
  • 由于cookie存储于客户端的数据,比较容易暴露,一般不存储一些敏感或者影响安全的数据

原理图:
1

应用场景举例

  1. 记录用户名 :
    第一次输入用户名,下一次用户名会自动填充
  2. 保存视频播放进度 :
    播放视频中途退出,下次进还在上次退出的地方继续播放。
    因为播放的时候会将播放进度保存到cookie中。

1.1 Cookie的使用

servletA向响应中增加Cookie

@WebServlet("/servletA")
public class ServletA extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建cookie
        Cookie cookie1 = new Cookie("keyA", "valueA");
        Cookie cookie2 = new Cookie("keyB", "valueB");
        //将cookie放入响应对象
        resp.addCookie(cookie1);
        resp.addCookie(cookie2);
    }
}

1

servletB从请求中读取Cookie

@WebServlet("/servletB")
public class ServletB extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        if (null != cookies && cookies.length != 0) {
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName() + "=" + cookie.getValue());
            }
        }
    }
}

1
2

1.2 Cookie的时效性

默认情况下Cookie的有效期是一次会话范围内,可以通过cookie的setMaxAge()方法让Cookie持久化保存到浏览器上

  • 会话级Cookie

    • 服务器端并没有明确指定Cookie的存在时间
    • 在浏览器端,Cookie数据存在于内存中
    • 只要浏览器还开着,Cookie数据就一直都在
    • 浏览器关闭,内存中的Cookie数据就会被释放
  • 持久化Cookie

    • 服务器端明确设置了Cookie的存在时间
    • 在浏览器端,Cookie数据会被保存到硬盘上
    • Cookie在硬盘上存在的时间根据服务器端限定的时间来管控,不受浏览器关闭的影响
    • 持久化Cookie到达了预设的时间会被释放

cookie.setMaxAge(int expiry)参数单位是秒,表示cookie的持久化时间,如果设置参数为0,表示将浏览器中保存的该cookie删除

  • servletA设置一个Cookie为持久化cookie
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建cookie
        Cookie cookie1 = new Cookie("keyA", "valueA");
        Cookie cookie2 = new Cookie("keyB", "valueB");
        //servletA COOKIE 存放 60秒 后消失
        cookie1.setMaxAge(60);
        //将cookie放入响应对象
        resp.addCookie(cookie1);
        resp.addCookie(cookie2);
    }
}
  • servletB接收Cookie,浏览器中间发生一次重启再请求servletB测试

1
60秒后 servletA消失
1

1.3 Cookie的提交路径

  • 访问互联网资源时,不能每次都把所有Cookie带上
  • 访问不同的资源时,可以携带不同的cookie,
  • 我们可以通过cookie的setPath(String path) 对cookie的路径进行设置
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建cookie
        Cookie cookie1 = new Cookie("keyA", "valueA");
        Cookie cookie2 = new Cookie("keyB", "valueB");
       //设置cookie的提交路径
        cookie1.setPath(req.getContextPath()+"/servletB");
        // " /cookie_session "
        System.out.println(req.getContextPath());
        //将cookie放入响应对象
        resp.addCookie(cookie1);
        resp.addCookie(cookie2);
    }
}

第一次访问 响应cookie:
3
访问servletB
2
访问servletC 只拿到 没有设置path 的"keyB" (设定了固定路径的拿不到)
1

二、Session

  • HttpSession是一种保留更多信息服务端的一种技术,
    • 服务端会为每一个客户端开辟一块内存空间,即session对象.
  • 客户端在发送请求时,都可以使用自己的session.
    • 这样服务端就可以通过session来记录某个客户端的状态
  • 服务端在为客户端创建session时,会同时将session对象id,即JSESSIONIDcookie的形式放入响应对象
  • 后端创建完session后,客户端会收到一个特殊的cookie,叫做JSESSIONID
  • 客户端下一次请求时携带JSESSIONID,后端收到后,根据JSESSIONID找到对应的session对象
  • 通过该机制,服务端通过session就可以存储一些专门针对某个客户端的信息了
  • session也是域对象

原理图:
2

应用场景

  1. 记录用户的登录状态
    用户登录后,将用户的账号等敏感信息存入session
  2. 记录用户操作的历史
    例如记录用户的访问痕迹,用户的购物车信息等临时性的信息

2.1 HttpSession的使用

用户提交form表单到ServletA,携带用户名,ServletA获取session 将用户名存到Session,用户再请求其他任意Servlet,获取之间存储的用户

  • 表单
<form action="servletC" method="post">
    用户名:
    <input type="text" name="username">
    <input type="submit" value="提交">
</form>
  • 定义servletC,将用户名存入session
@WebServlet("/servletC")
public class ServletC extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        //获取请求中的session对象
        HttpSession session = req.getSession();
        //获取session的ID
        String id = session.getId();
        System.out.println(id);
        //判断session是不是新创建的session
        boolean isNew = session.isNew();
        System.out.println(isNew);
        //向session对象中存入数据
        session.setAttribute("username",username);
    }
}
  • 响应中收到JSESSIONID的cookie
    1
  • 定义其他的servlet,从session中读取用户名
@WebServlet("/servletD")
public class ServletD extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session对象
        HttpSession session = req.getSession();
        //获取session的ID
        String id = session.getId();
        //判断是否是新创建的session
        boolean isNew = session.isNew();
        System.out.println(isNew);
        //从session中取出数据
        String username = (String) session.getAttribute("username");
        System.out.println(username);
    }
}
  • 请求中携带 JSESSIONID的cookie
    2
  • session 的ID
    1

getSession方法的处理逻辑
1

2.2 HttpSession时效性

为什么要设置session的时效

  • 用户量很大之后,Session对象相应的也要创建很多。
    • 如果一味创建不释放,那么服务器端的内存迟早要被耗尽。
  • 客户端关闭行为无法被服务端直接侦测,或者客户端较长时间不操作也经常出现,类似这些的情况,就需要对session的时限进行设置了

默认的session最大闲置时间(两次使用同一个session中的间隔时间) 在tomcat/conf/web.xml配置为30分钟
1

我们可以自己在当前项目的web.xml最大闲置时间进行重新设定
1

  • 也可以通过HttpSession的API 对最大闲置时间进行设定
// 设置最大闲置时间
session.setMaxInactiveInterval(60);
  • 也可以直接让session失效
// 直接让session失效
session.invalidate();

三、三大域对象

3.1 域对象概述

域对象:

  • 一些用于存储数据和传递数据的对象,
  • 传递数据不同的范围,我们称之为不同的域,
  • 不同的域对象代表不同的域,共享数据的范围也不同
  • web项目中,熟练使用的域对象分别是 请求域,会话域,应用域
  • 请求域对象是HttpServletRequest,传递数据的范围是一次请求之内及请求转发
  • 会话域对象是HttpSession,传递数据的范围是一次会话之内,可以跨多个请求
  • 应用域对象是ServletContext,传递数据的范围是本应用之内,可以跨多个会话

三大域对象的数据作用范围图解 :

  • 请求域
    客户端发送一次的请求,以及,请求转发
    1
  • 会话域 :
    同一个客户端,跨多个请求 传递信息,
    举例:servletA可以servletB、C、D也可以接受信息,只要拿到session对应的cookie
    1
  • 应用域
    跨客户端 , 另一个客户端也能取到数据
    2
  • 所有域 合体
    1

3.2 域对象的使用

域对象的API:

API功能
void setAttribute(String name,String value)向域对象中添加/修改数据
Object getAttribute(String name);从域对象中获取数据
removeAttribute(String name);移除域对象中的数据

API测试:

@WebServlet("/servletE")
public class ServletE extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建 请求域
        req.setAttribute("reqKeyE","reqValueE");

        // 创建 会话域
        HttpSession session = req.getSession();
        System.out.println("E sessionID: "+session.getId());
        session.setAttribute("sessionKeyE","sessionValueE");

        // 创建 应用域
        ServletContext application = this.getServletContext();
        application.setAttribute("servletContextKeyE","servletContextValueE");

        // 请求域 获取 一次请求
        String reqKeyE = (String)req.getAttribute("reqKeyE");
        System.out.println("ServletE REQ : "+reqKeyE);

        // 请求域 之 请求转发
        req.getRequestDispatcher("servletF").forward(req,resp);
    }
}
@WebServlet("/servletF")
public class ServletF extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 尝试直接获取servletE的请求域 (不可能获取到)
        String reqKeyE = (String)req.getAttribute("reqKeyE");
        System.out.println("ServletF REQ: " + reqKeyE);
        // 请求域 servletE开启请求转发 是可以获取 servletE的域中值
        String reqKeyEForward = (String)req.getAttribute("reqKeyE");
        System.out.println("ServletF Forward: " + reqKeyEForward);

        //会话域 获取
        HttpSession session = req.getSession();
        String sessionKeyE = (String)session.getAttribute("sessionKeyE");
        System.out.println("F get session id : "+session.getId());
        System.out.println("F session By KeyE: "+ sessionKeyE);

        // 应用域 获取
        ServletContext application = this.getServletContext();
        String servletContextKeyE = (String)application.getAttribute("servletContextKeyE");
        System.out.println("ServletF 应用域获取: "+servletContextKeyE);
    }
}

结果:

  1. 开启servletE 的请求转发 给servletF:
    1
  2. 没开启请求转发:
    2

总结:

  1. 请求域 : 域值传入与读取的范围 -> 当前servlet内 一次请求 以及 请求转发
  2. 会话域:同一客户端,两个或多个servlet 信息传递
  3. 应用域:不同客户端,开启共享域,都可以获取到存入的数据,也都能存入

总结

  • 请求转发时,请求域可以传递数据请求域内一般放本次请求业务有关的数据,
    • 如:查询到的所有的部门信息
  • 同一个会话内,不用请求转发,会话域可以传递数据会话域内一般放本次会话的客户端有关的数据,
    • 如:当前客户端登录的用户
  • 同一个APP内,不同的客户端,应用域可以传递数据应用域内一般放本程序应用有关的数据
    • 如:Spring框架的IOC容器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/346736.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决Sublime Text V3.2.2中文乱码问题

目录 中文乱码出现情形通过安装插件来解决乱码问题 中文乱码出现情形 打开一个中文txt文件&#xff0c;显示乱码&#xff0c;在File->Reopen With Encoding里面找不到支持简体中文正常显示的编码选项。 通过安装插件来解决乱码问题 安装Package Control插件 打开Tool->…

【数据结构与算法】栈(Stack)之 浅谈数组和链表实现栈各自的优缺点

文章目录 1.栈介绍2. 哪种结构实现栈会更优&#xff1f;3.栈代码实现&#xff08;C语言&#xff09; 往期相关文章&#xff1a; 线性表之顺序表线性表之链表 1.栈介绍 栈是一种特殊的线性表&#xff0c;只允许在栈顶&#xff08;Top&#xff09;进行插入和删除元素操作&#…

【项目日记(四)】第一层: 线程缓存的具体实现

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你做项目   &#x1f51d;&#x1f51d; 开发环境: Visual Studio 2022 项目日…

Unity中URP下获取每一个额外灯数据

文章目录 前言一、我们先来看一下 SimpleLit 中的调用二、获取额外灯索引1、非移动平台2、非GLES平台3、大多数平台 三、获取额外灯数据 前言 在上一篇文章中&#xff0c;我们知道了URP下是怎么获取额外灯数量的。 Unity中URP下获取额外灯数量 在这篇文章中&#xff0c;我们…

场内基金出货是什么意思?出货和洗盘有什么区别?

场内基金出货是股市中常见的一种操作策略&#xff0c;指股市中的投资大户或者机构大量或者批次买入某只股票&#xff0c;并散发利好该股票的消息&#xff0c;导致该股票在短时间内股价升高&#xff0c;从而吸引投资散户购买该股票。等到股价上升到一定的阶段时&#xff0c;庄家…

nextjs中beforePopState使用

在某些情况下&#xff0c;希望监听popstate并在路由器对其进行操作之前执行某些操作。可以使用beforePopState。 在Next.js中&#xff0c;beforePopState是一个可选的生命周期函数&#xff0c;用于在浏览器的历史记录发生更改之前执行一些操作。具体来说&#xff0c;beforePopS…

两千字讲明白java中instanceof关键字的使用!

写在开头 在过往的内容中&#xff0c;我们讲了不少的Java关键字&#xff0c;比如final、static、this、super等等&#xff0c;Java中的关键字非常之多&#xff0c;下图是整理的关键字集合 而我们今天要学习的就是其中的instanceof关键字&#xff01; instanceof的定义 instanc…

k8s安全机制

安全机制&#xff1a;k8s的安全机制&#xff0c;分布式集群管理工具&#xff0c;就是容器编排。 安全机制的核心&#xff1a;API SERVER作为整个集群内部通信的中介&#xff0c;也是外控控制的入口。所有的安全机制都是围绕api server来进行设计&#xff1a; 请求api资源&#…

数据结构·单链表

不可否认的是&#xff0c;前几节我们讲解的顺序表存在一下几点问题&#xff1a; 1. 中间、头部的插入和删除&#xff0c;需要移动一整串数据&#xff0c;时间复杂度O(N) 2. 增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间。会有不小的消耗 3. 增容一般是2倍的增…

MySQL安装及可视化工具SQLyog下载

编程如画&#xff0c;我是panda&#xff01; 最近学习Web开发的时候要用到数据库&#xff0c;一开始下载的ZIP版本的&#xff0c;还得修改配置文件&#xff0c;挺麻烦的&#xff0c;后来发现可以直接使用msi版的安装包疯狂next&#xff0c;所以就出一期教程。 前言 MySQL 是一…

链表--104. 二叉树的最大深度/medium 理解度A

104. 二叉树的最大深度 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,n…

22款奔驰GLS450升级香氛负离子车载香薰功能

奔驰原厂香氛系统激活原车自带系统&#xff0c;将香气加藏储物盒中&#xff0c;通过系统调节与出风口相结合&#xff0c;再将香味传达至整个车厢&#xff0c;达到净化车厢空气的效果&#xff0c;让整个车厢更加绿色健康&#xff0c;清新淡雅。星骏汇小许Xjh15863 产品功能&…

Vue3+Vite使用Puppeteer进行SEO优化(SSR+Meta)

1. 背景 【笑小枫】https://www.xiaoxiaofeng.com上线啦 资源持续整合中&#xff0c;程序员必备网站&#xff0c;快点前往围观吧~ 我的个人博客【笑小枫】又一次版本大升级&#xff0c;虽然知道没有多少访问量&#xff0c;但我还是整天没事瞎折腾。因为一些功能在Halo上不太好实…

MES管理系统计划排产有哪些重要作用

在当今制造业中&#xff0c;MES管理系统解决方案已经成为提高生产效率、优化资源利用以及提升企业整体运营水平的关键工具。尤其是在生产计划排产这一核心环节&#xff0c;MES管理系统发挥着无可替代的作用。通过精准的计划和调度&#xff0c;MES管理系统帮助企业实现生产过程的…

SAP EXCEL上传如何实现指定读取某一个sheet页(ALSM_EXCEL_TO_INTERNAL_TABLE)

如何读取指定的EXCEL sheet 页签&#xff0c;比如要读取下图中第二个输出sheet页签 具体实现方法如下&#xff1a; 拷贝标准的函数ALSM_EXCEL_TO_INTERNAL_TABLE封装成一个自定义函数ZCALSM_EXCEL_TO_INTERNAL_TABLE 在自定义函数导入参数页签新增一个参数SHEET_NAME 在源代码…

【word密码】Word 文档设置了只读为什么还能编辑?

有些朋友可能会遇到这种疑问&#xff0c;为什么我的Word文档设置了只读模式&#xff0c;还是可以编辑的&#xff0c;这是什么原因呢&#xff1f; 其实是因为大部分的只读模式&#xff0c;设置完成之后都是可以编辑的&#xff0c;但是当我们进行保存的时候就会发现&#xff0c;…

【边缘计算】TA的基本概念,以及TA的挑战和机遇

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读文章&#xff01; 此篇是【话题达人】序列文章&#xff0c;这一次的话题是《边缘计算的挑战和机遇》 文章将以博主的角度进行讲述&#xff0c;理解和水平有限&#xff0c;不足之处&#xff0c;望指正。 目录 背景基本概念挑战…

软件游戏提示msvcp140.dll丢失的解决方法,全面分析msvcp140.dll文件

msvcp140.dll是Microsoft Visual C 2015 Redistributable的一部分&#xff0c;它包含了许多用于运行程序的函数和类库。当这个文件丢失或损坏时&#xff0c;依赖于该组件的应用程序可能无法正常启动&#xff0c;系统会弹出错误提示&#xff0c;告知用户找不到msvcp140.dll文件。…

【Linux】糟糕,是心动的感觉——与Linux的初次相遇

初识Linux 导言一、计算机的发展1.1 历史背景1.2 计算机的发明 二、操作系统2.1 什么是操作系统&#xff1f;2.2 操作系统的诞生2.3 操作系统的发展2.3.1 批处理系统的发展2.3.2 分时系统2.3.3 实时系统2.3.4 通用操作系统 2.4 UNIX操作系统2.4.1 UNIX的诞生2.4.2 UNIX的发展 2…

ESXI 本地和虚拟机之间可以自由复制和粘贴

文章目录 ESXI 本地和虚拟机之间可以自由复制和粘贴 ESXI 本地和虚拟机之间可以自由复制和粘贴 web访问esxi&#xff0c;然后&#xff1a; 1、右击新建的虚拟机&#xff0c;确保是在关机状态下&#xff0c;点击编辑设置 2. 找到 虚拟机选项→高级→常规→配置参数 3、点击添加…