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

news2024/11/14 6:11:24

文章目录

  • 会话管理
  • 一、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容器

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GIt同时存在传入和传出更改修改,无法合并

前言 Git是常用的版本管理工具&#xff0c;之前面试被问到过一次——Git有无遇到过使用错误情况&#xff1f;当时卡壳了没答上来&#xff0c;所以这次遇到&#xff0c;特此记录学习。 问题概述 前一天提交了代码&#xff0c;mt进行了修改。但我忘记拉取最新&#xff0c;就进…

1.19号网络

超时检测 概念 1> 在网络通信中&#xff0c;有很多函数是阻塞函数&#xff0c;会导致进程的阻塞&#xff0c;例如&#xff1a;accept、recv、recvfrom、等等 2> 为了避免进程在阻塞函数处&#xff0c;无休止的等待&#xff0c;我们可以设置一个超时时间&#xff0c;当…

【云原生】Docker的端口映射、数据卷、数据卷容器、容器互联

目录 一、端口映射&#xff08;相当于添加iptables的DANT&#xff09; 二、数据卷创建&#xff08;宿主机目录或文件挂载到容器中&#xff09; 三、数据卷容器&#xff08;多个容器通过同一个数据卷容器为基点&#xff0c;实现所有容器数据共享&#xff09; 四、容器互联&am…

尝试给docker ubuntu22.04镜像添加远程访问桌面

实在时不愿折腾&#xff0c;但是ubuntu 镜像没有桌面&#xff0c;有些操作实在太难受了&#xff0c;效率也不高。硬着头皮上吧。幸亏这是个docker的镜像。要是个虚拟机&#xff0c;这折腾来去&#xff0c;直接崩溃了。docker的好处就是立马就能从头来过&#xff0c;秒级的删除安…

Hive常见问题汇总

Hive和Hadoop的关系 Hive 构建在 Hadoop 之上&#xff0c; HQL 中对查询语句的解释、优化、生成查询计划是由 Hive 完成的 所有的数据都是存储在 Hadoop 中 查询计划被转化为 MapReduce 任务&#xff0c;在 Hadoop 中执行&#xff08;有些查询没有 MR 任务&#xff0c;如&…

07 队列

目录 1.队列 2.实现 3.OJ题 1. 队列 只允许在一段进行插入数据操作&#xff0c;在另一端进行数据删除操作的特殊线性表&#xff0c;队列具有先进先出FIFO&#xff08;First In Firtst Out&#xff09;&#xff0c;插入操作的叫队尾&#xff0c;删除操作的叫队头 2. 实现 队列…

PWM调光 降压恒流LED芯片FP7127:为照明系统注入新能量(台灯、GBR、调光电源、汽车大灯)

目录 一、降压恒流LED芯片FP7127 二、降压恒流LED芯片FP7127具有以下特点&#xff1a; 三、降压恒流LED芯片FP7127应用领域&#xff1a; LED照明和调光的新纪元随着LED照明技术的不断发展&#xff0c;人们对于照明调光的需求也越来越高。PWM调光技术作为一种常用的调光方法&…

微软 AD 介绍 | 安全建议 | 防护

介绍&#xff1a; 什么是Active Directory&#xff08;AD&#xff09;&#xff1f; Active Directory 是由 微软开发的目录服务&#xff0c;用于存储和管理网络中的资源&#xff0c;如计算机、用户、组和其他网络对象。允许组织管理员轻松地管理和验证网络中的用户和计算机。 …

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

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

[IO复用] IO复用问答

记录一下IO复用相关的基础知识。 文章目录 阻塞和非阻塞同步和异步为什么使用IO复用什么是IO复用IO复用有哪些方式select IO复用poll IO复用epoll IO复用什么时候用select 或者 epoll&#xff1f; select、poll、epoll的区别Windows中的IO复用Reactor模式C10K问题C10M问题 面试…

【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用

系列文章目录 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part1 案例复现 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part2 自有数据集构建 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用 在一个人体姿态估计的任务中&#xff0c;需要用深度学习模型…

【Vue3】组件通信

Vue3组件通信和Vue2的区别&#xff1a; 移出事件总线&#xff0c;使用mitt代替。vuex换成了pinia。把.sync优化到了v-model里面了。把$listeners所有的东西&#xff0c;合并到$attrs中了。$children被砍掉了。 1. props 若 父传子&#xff1a;属性值是非函数。若 子传父&…

【解决】IntelliJ IDEA 重命名 Shift + F6 失效

IntelliJ IDEA 重命名 Shift F6 失效 问题解决 问题 Idea 重命名 Shift F6 &#xff0c;一直没反应 解决 调查发现原因是微软新版的输入法冲突了。需要设置【使用以前版本的微软拼音输入法】解决兼容性。 设置 -> 时间和语言 -> 区域 -> 语言选项 -> 键盘选项…

ELK之使用Grafana读取ES集群的Nginx日志进行分析展示

一、前提&#xff1a; 直通车 ------------>↓↓↓↓↓↓ 需要ES集群 https://blog.csdn.net/wdy_2099/article/details/125441436需要filebeat https://blog.csdn.net/wdy_2099/article/details/125445893需要logstash https://blog.csdn.net/wdy_2099/article/details/1…

技术变革下职业危机

方向一&#xff1a;技术变革 1.人工智能&#xff08;AI&#xff09;&#xff1a;AI技术的快速发展正在改变各个行业。AI在医疗诊断、金融分析、客户服务以及物流管理等方面都有广泛应用&#xff0c;提高了效率和准确性。但同时也引发了一些道德和道德问题&#xff0c;比如隐私…

Redis的五种常用数据类型详解及相关面试问题

目录 Redis的五种常用数据类型详解 简述 Redis五种基本数据类型 String字符串 常用命令 应用场景 Hash散列表 常用命令 使用场景 List链表 常用命令 应用场景 Set( 集合) 常用命令 应用场景 SortedSet( 有序集合) zset 常用命令介绍 应用场景 面试题常问的数…

【MySQL】打开科技创新的第一生产力

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-EtRkflNU19AGWAkT {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

景联文科技大模型数据集更新!教育题库新增高质量数学题、逻辑推理题及英文题

苏格拉底曾以“点燃火焰”的理念来诠释教育。随着大语言模型在教育中的不断应用&#xff0c;教育与AI的深度融合&#xff0c;让我们看到了“点燃火焰”的理念的更多可能性。 大语言模型可以通过与学生的互动&#xff0c;为他们提供个性化的学习体验&#xff0c;更好地满足学习需…

Maven简述

Maven是用于管理和构建Java项目的工具&#xff0c;提供了一套标准化的项目结构&#xff0c;提供了一套标准化的构建流程&#xff0c;提供了一套依赖管理机制&#xff0c;通过Maven使得所有IDE构建的项目结构完全一样&#xff0c;让项目可以通用。 项目名称下分为src 和 pom.xm…

差分进化算法求解基于移动边缘计算 (MEC) 的无线区块链网络的联合挖矿决策和资源分配(提供MATLAB代码)

一、优化模型介绍 在所研究的区块链网络中&#xff0c;优化的变量为&#xff1a;挖矿决策&#xff08;即 m&#xff09;和资源分配&#xff08;即 p 和 f&#xff09;&#xff0c;目标函数是使所有矿工的总利润最大化。问题可以表述为&#xff1a; max ⁡ m , p , f F miner …