JAVAWeb10-Web 开发会话技术-Session-02

news2024/11/26 14:29:15

1. session 有什么用

● 思考两个问题—抛砖引玉

  1. 不同的用户登录网站后,不管该用户浏览该网站的哪个页面,都可显示登录人的名字,还可以随时去查看自己的购物车中的商品, 是如何实现的?
  2. 也就是说,一个用户在浏览网站不同页面时,服务器是如何知道是张三在浏览这个页面,还是李四在浏览这个页面?
    在这里插入图片描述
  3. 同学们想想,如果让你来实现这个功能,你会如何完成?
    在这里插入图片描述
  • 解决之道—session 技术, 简单说
  1. Session 是服务器端技术,服务器在运行时为每一个用户的浏览器创建一个其独享的session 对象/集合
    在这里插入图片描述

  2. 由于 session 为各个用户浏览器独享,所以用户在访问服务器的不同页面时,可以从各自的 session 中读取/添加数据, 从而完成相应任务

2. session 基本原理

2.1 Sesson 原理示意图

在这里插入图片描述

  1. 当用户打开浏览器,访问某个网站, 操作 session 时,服务器就会在内存(在服务端)为该浏览器分配一个 session 对象,该 session 对象被这个浏览器独占, 如图
  2. 这个 session 对象也可看做是一个容器/集合,session 对象默认存在时间为 30min(这是在tomcat/conf/web.xml),也可修改
    在这里插入图片描述

2.2 Session 可以做什么

  1. 网上商城中的购物车
  2. 保存登录用户的信息
  3. 将数据放入到 Session 中,供用户在访问不同页面时,实现跨页面访问数据
  4. 防止用户非法登录到某个页面

2.3 如何理解 Session

  1. session 存储结构示意图
    在这里插入图片描述
  2. 你可以把 session 看作是一容器类似 HashMap,有两列(K-V),每一行就是 session 的一个属性。
  3. 每个属性包含有两个部分,一个是该属性的名字(String),另外一个是它的值(Object)

3. session 常用方法

3.1 文档

java_ee_api_中英文对照版.chm

3.2 Session 的基本使用

在这里插入图片描述

  1. 创建和获取 Session,API 一样
    HttpSession hs=request.getSession();
    第 1 次调用是创建 Session 会话, 之后调用是获取创建好的 Session 对象

  2. 向 session 添加属性
    hs.setAttribute(String name,Object val);

  3. 从 session 得到某个属性
    Object obj=hs.getAttribute(String name);

  4. 从 session 删除调某个属性:
    hs.removeAttribute(String name);

  5. isNew(); 判断是不是刚创建出来的 Session

  6. 每个 Session 都有 1 个唯一标识 Id 值。通过 getId() 得到 Session 的会话 id 值

4. session 底层实现机制

4.1 原理分析图(一图胜千言)

session 底层实现机制图解(重要)
在这里插入图片描述
在这里插入图片描述

4.2 实例分析

  1. 需求:演示 Session 底层实现机制-创建和读取 Session
  2. (回顾之前手写Tomcat的项目)
    添加容器:sessionMapping
public class HspTomcatV3 {

    //1. 存放容器 servletMapping
    // -ConcurrentHashMap
    // -HashMap
    // key            - value
    // ServletName    对应的实例

    public static final ConcurrentHashMap<String, HspHttpServlet>
            servletMapping = new ConcurrentHashMap<>();


    //2容器 servletUrlMapping
    // -ConcurrentHashMap
    // -HashMap
    // key                    - value
    // url-pattern       ServletName

    public static final ConcurrentHashMap<String, String>
            servletUrlMapping = new ConcurrentHashMap<>();


    //你可以这里理解session, tomcat还维护一个容器
    public static final ConcurrentHashMap<String, HttpSession>
            sessionMapping = new ConcurrentHashMap<>();

	。。。。。。。
}
  1. 创 建 CreateSession.java
public class CreateSession extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println("CreateSession 被调用...");

        //1. 获取session, 同时也可能创建session
        HttpSession session = request.getSession();

        //2. 给session获取id
        System.out.println("CreateSession 当前sessionid= " + session.getId());
        //3. 给session存放数据
        session.setAttribute("email", "zs@qq.com");

        //4. 给浏览器发送一个回复
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>创建/操作session成功...</h1>");
        writer.flush();
        writer.close();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

测试 Session 创建的机制, 注意抓包分析:
(按照分析图3种情况测试分析请求、响应的信息)
在这里插入图片描述

补充说明:
当浏览器第一次访问Tomcat服务器时,Tomcat会为该会话创建一个唯一的标识符JsessionId。这是因为JsessionId是用于跟踪用户会话的关键参数,可以确保在同一个会话期间用户的多次请求都被映射到同一个会话上下文中处理。在后续的请求中,浏览器将JsessionId作为cookie或URL参数发送给服务器,以便服务器能够识别并恢复与该特定会话相关联的所有状态和信息。
补充:
启动Tomcat默认会访问一个jsp文件,此时会生成返回一个JsessionId,但是没有为该id生成对象

  1. 创 建 测试读取
    ReadSession.java
public class ReadSession extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println("ReadSession 被调用...");
        // 演示读取session
        //1. 获取session, 如果没有sesion, 也会创建
        HttpSession session = request.getSession();
        //输出sessionId
        System.out.println("ReadSession sessionid= " + session.getId());
        //2. 读取属性
        Object email = session.getAttribute("email");
        if (email != null) {
            System.out.println("session属性 email= " + (String) email);
        } else {
            System.out.println("session中没有 email属性 ");
        }
        //给浏览器回复一下
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>读取session成功...</h1>");
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

测试 Session 读取的机制, 注意抓包分析
在这里插入图片描述

  1. 有了代码支撑,我们在回头看 Session 的原理图,就有更深刻的理解

4.3 Session 实现原理动画

● 服务器是如何实现一个 session 为一个用户浏览器服务的
在这里插入图片描述

5. session 生命周期

5.1 Session 生命周期-说明

  1. public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁。

  2. 值为正数的时候,设定 Session 的超时时长。

  3. 负数表示永不超时

  4. public int getMaxInactiveInterval()获取 Session 的超时时间

  5. public void invalidate() 让当前 Session 会话立即无效

  6. 如果没有调用 setMaxInactiveInterval() 来指定 Session 的生命时长,Tomcat 会以 Session默认时长为准,Session 默认的超时为 30 分钟, 可以在 tomcat 的 web.xml 设置
    在这里插入图片描述

  7. Session 的生命周期指的是 :客户端/浏览器两次请求最大间隔时长,而不是累积时长。即当客户端访问了自己的 session,session 的生命周期将从 0 开始重新计算。(解读: 指的是同一个会话两次请求之间的间隔时间)
    在这里插入图片描述

  8. 底层: Tomcat 用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁
    在这里插入图片描述

5.2 Session 生命周期-应用实例

● 需求:代码演示说明 Session 的生命周期
● 代码实现

  1. 创 建 CreateSession2.java
public class CreateSession2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CreateSession2 被调用");
        //创建session
        HttpSession session = request.getSession();
        System.out.println("CreateSession2 sid= " + session.getId());
        //设置生命周期为 60s
        session.setMaxInactiveInterval(60);
        session.setAttribute("u", "jack");

        //回复一下浏览器
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>创建session成功, 设置生命周期60s</h1>");
        writer.flush();
        writer.close();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  1. 创 建 ReadSession2.java
public class ReadSession2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println("ReadSession2 被调用...");

        //1. 获取到session
        HttpSession session = request.getSession();
        System.out.println("ReadSession2 sid= " + session.getId());
        //2. 读取session的属性
        Object u = session.getAttribute("u");
        if (u != null) {
            System.out.println("读取到session属性 u= " + (String) u);
        } else {
            System.out.println("读取不到session属性 u 说明原来的session被销毁");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

解读:Session 的生命周期

  1. 指的是两次访问 session 的最大间隔时间
  2. 如果你在 session 没有过期的情况下,操作 session,则会重新开始计算生命周期
  3. session 是否过期,是由服务器来维护和管理
  4. 如我们调用了 invaliate() 会直接将该,session 删除/销毁
  5. 如果希望删除 session 对象的某个属性, 使用 removeAttribute(“xx”)
  1. 创 建 DeleteSession.java
public class DeleteSession extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("DeleteSession 被调用...");

        //演示如何删除session
        HttpSession session = request.getSession();
        session.invalidate();

        //再多说一句, 如果你要删除session的某个属性
        //session.removeAttribute("xxx");

        //回复一下浏览器
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>删除session成功</h1>");
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

完成测试 , 使用前面编写的文件来演示说明 Session 的生命周期.

6. Session 经典案例-防止非法进入管理页面

6.1 作业布置

  1. 需求说明: 完成防止用户登录管理页面应用案例(如图)
    在这里插入图片描述
    说明:
  1. 只要密码为 666666, 我们认为就是登录成功
  2. 用户名不限制
    2.1 如果验证成功,则进入管理页面 ManageServelt.java
    2.2 如果验证失败,则进入 error.html
  1. 如果用户直接访问 ManageServet.java , 重定向到到 login.html

登录界面:userLogin.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
<h1>用户登录</h1>
<form action="/cs/loginCheck"
      method="post">
    用户名:<input type="text" name="username"/><br/><br/>
    密 码:<input type="password" name="password"><br><br/>
    <input type="submit" value="登录"></form>
</body>
</html>

登录失败页面:error.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录失败</title>
</head>
<body>
<h1>登录失败</h1>
<!--
回顾 web工程路径专题
1. a 标签是 浏览器解析
2. 第一 / 被解析成 http://localhost:8080/
3. 如果没有 / 会以当前浏览器地址栏 的 http://localhost:8080/工程路径../资源 去掉资源部分作为参考路径
4  其它的回顾请大家看 web工程路径专题~~ , 他会贯彻 整个java后端开发
-->
<a href="/cs/userlogin.html">点击重新登录</a>
</body>
</html>

LoginCheckServlet.java

public class LoginCheckServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("LoginCheckServlet 被调用..");
        //功能-> 自己拆解 -> 逐步实现 [大量练习]
        //1. 得到提交的用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if("666666".equals(password)) {//认为合法
            //把用户名保存到 session
            HttpSession session = request.getSession();
            session.setAttribute("loginuser", username);

            //请求转发到ManageServlet
            request.getRequestDispatcher("/manage").forward(request, response);
        } else {
            //请求转发进入到 error.html
            request.getRequestDispatcher("/error.html").forward(request, response);
        }


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

ManageServlet.java

public class ManageServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //判断该用户是否登录过
        HttpSession session = request.getSession();
        Object loginuser = session.getAttribute("loginuser");
        if(loginuser == null) {//说明该用户没有登录
            //重新登录-> 请求重定向
            //response.sendRedirect("/cs/userlogin.html");
            response.sendRedirect(request.getContextPath() + "/userlogin.html");
            return;
        } else {
            response.setContentType("text/html;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.println("<h1>用户管理页面</h1>");
            writer.println("欢迎你, 管理员:" + loginuser.toString());
            writer.flush();
            writer.close();
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

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

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

相关文章

如何高效的学习接口自动化测试?从零开始学习接口自动化测试:选择合适的学习资源和编程语言

目录 引言&#xff1a; 一、学习前的准备 二、选择合适的学习资源 三、实践中学习 四、总结 引言&#xff1a; 在日常的软件开发过程中&#xff0c;接口自动化测试是一个非常重要的环节。接口自动化测试可以帮助我们快速准确地检测出软件中的缺陷&#xff0c;提高软件的质…

更简单的存取Bean方式-@Bean方法注解

1.Bean方法存储 类注解是添加在某个类上的,那么方法注解是添加在某个方法前的 public class UserBeans {Beanpublic User user1(){User user new User();user.setUid(001);user.setUname("zhangsan");user.setAge(19);user.setPassword("123123");retur…

Git/Github操作手册

Git 是目前最流行的版本管理工具&#xff0c;也是程序员的必备技能之一。 这里主要介绍一下git/github远程仓库的使用及相关配置&#xff1a; 一、SSH Keys SSH Keys是什么呢&#xff1f;简单来说相当于一把钥匙&#xff08;在机器中即电脑中进行配置&#xff09;&#xff0…

【Java数据结构】——第九节.向上建堆和向下建堆的区别

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;Java初阶数据结构 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目…

算法训练 | Day41动态规划

343. 整数拆分 思路&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp[i]&#xff1a;分拆数字i&#xff0c;可以得到的最大乘积为dp[i]。 确定递推公式&#xff1a;dp[i] max(dp[i], max((i - j) * j, dp[i - j] * j)) 可以想 dp[i]最…

TimesNet

Key Points 1D变2D 这是本文的核心。大部分现有方法都是作用于时间序列的时间维度&#xff0c;捕获时序依赖性。实际上&#xff0c;现实时间序列一般都有多种模式&#xff0c;比如不同的周期&#xff0c;各种趋势&#xff0c;这些模式混杂在一起。如果直接对原始序列的时间维…

SpringTask任务调度工具的使用

1. Spring Task 1.1 介绍 Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 **定位&#xff1a;**定时任务框架 **作用&#xff1a;**定时自动执行某段Java代码 应用场景&#xff1a; 1). 信用卡每月还款提醒 **强调&…

网络机顶盒哪个好?发烧友实测2023网络机顶盒排名

不懂网络机顶盒哪个好的新手们在选购时大部分会参考排行榜&#xff0c;某知名权威数码网站公布了2023年最新网络机顶盒排名&#xff0c;结果是否公正呢&#xff1f;我自费购入了排名前五的网络机顶盒&#xff0c;进行了十多天的深入测评&#xff0c;今天就来详细聊聊我的真实体…

最近部门新的00后真是卷王,工作没1年,入职18K

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。 这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没1年&#xff0c;到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 …

2.2 逻辑代数中的三种基本运算

学习建议&#xff1a; 理解运算符的含义&#xff1a;首先&#xff0c;我们需要理解每个逻辑运算符的含义。例如&#xff0c;“与”运算符表示两个输入信号同时为真时输出为真&#xff0c;而“或”运算符表示两个输入信号中至少一个为真时输出为真。 练习运算符的应用&#xff…

使用openssl生成https证书

首先去官网下载openssl工具&#xff1a;Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions (slproweb.com) 然后安装完成需要执行&#xff08;1&#xff09;openssl genrsa -des3 -out root.key 1024 &#xff08;2&#xff09;openssl req -new -key ro…

Java面试题总结 | Java面试题总结7- 计算机网络模块(持续更新)

计算机网络 文章目录 计算机网络get和post的区别TCP和UDPTCP和UDP的应用层协议TCP是如何保证可靠传输的视频聊天用的是TCP还是UDP&#xff0c;为什么可靠的UDP协议UDT(UDP-based Data Transfer Protocol)KCPQUIC Cookie和Session的区别Cookie的优缺点cookie的优点&#xff1a;c…

连ChatGPT都不懂的五一调休,到底怎么来的?

今天是周几&#xff1f; 你上了几天班了&#xff1f; 还要上几天班放假&#xff1f; 五一啥安排&#xff1f; 出行的票抢到了吗&#xff1f; 调休到底是谁发明的&#xff1f;&#xff01; 五一劳动节是要劳动吗&#xff1f; 为什么昨天是周一&#xff0c;今天还是周一&a…

跨域融合风口下,又一外资巨头Tier 1+本土供应商“组团”来袭

头部企业正在加速“融合”。 汽车智能化升级对产品创新与多元化需求下&#xff0c;来自技术升级、降本、开发周期缩短等等一系列因素影响&#xff0c;中外供应商们都在积极思变和寻求破局。 随着全球智能汽车产业步入域集中和域融合的新阶段&#xff0c;过去的以硬件&#xf…

找不到vcruntime140_1.dll无法执行的问题解决方案

随着技术的不断进步&#xff0c;人们越来越依赖电脑来处理日常工作。时常在安装或运行一些软件的时候&#xff0c;我们可能会碰到一些提示信息&#xff0c;其中的“找不到vcruntime140_1.dll无法执行”就是很常见的一种。今天我们就来探讨一下这个问题的原因和解决方案。 一.vc…

第八章 C#脚本(上)

脚本是使用 Unity 开发的所有应用程序中必不可少的组成部分。大多数应用程序都需要脚本来响应玩家的输入并安排游戏过程中应发生的事件。游戏对象的行为由附加的组件控制。虽然Unity内置了许多组件&#xff0c;但是我们仍然可以使用脚本来创建自定义组件。Unity支持C#编程脚本语…

用友T3提示,年度[UFDATA_002_2017]并不存在,导致无法备份迁移。

用友T3提示&#xff0c;年度[UFDATA_002_2017]并不存在&#xff0c;导致无法备份迁移。 现在都win11&#xff0c;迁移T3到新电脑&#xff0c;遇到了问题&#xff0c;某个年度账套不存在怎么办&#xff1f; 打开数据管理工具。无法导出。 002代表账套编号&#xff0c;2017代表…

【Zookeeper】 面试题总结

Zookeeper 1、工作中 Zookeeper 有什么用途吗2、zookeeper 数据模型是什么样的3、那你知道 znode 有几种类型呢4、你知道 znode 节点里面存储什么吗5、每个节点数据最大不能超过多少呢6、你知道 znode 节点上监听机制嘛7、那你讲下 Zookeeper 特性吧8、你刚提到顺序一致性&…

计算机网络-基础编程实验(JAVA\Python3)

计算机网络-网络基础编程实验(JAVA\Python3) 一.实验目的 通过本实验&#xff0c;学习采用Socket&#xff08;套接字&#xff09;设计简单的网络数据收发程序&#xff0c;理解应用数据包是如何通过传输层进行传送的。 二.实验内容 学习套接字编程&#xff0c;完成以下的网络数…

海尔牵头IEEE P2786国际标准通过Sponsor投票并连任工作组主席

01 海尔牵头IEEE P2786国际标准 通过Sponsor投票 并连任工作组主席 海尔牵头制定的全球首个服装物联网国际标准IEEE P2786《Standard for General Requirements and Interoperability for Internet of Clothing》通过Sponsor投票&#xff0c;标志着该国际标准草案得到了行业…