JavaWeb系列十一: Web 开发会话技术Session
Web 开发会话技术Session
- Session有什么用
- session基本原理
- session原理示意图
- session可以做什么
- 如何理解Session
- Session常用方法
- Session底层实现机制
- 原理分析图
- 应用实例
- session实现原理动画
- Session生命周期
- Session生命周期说明
- Session生命周期实例
- 作业布置
Session有什么用
●思考两个问题
1.不同的用户登陆后, 不管该用户浏览网站的哪个页面, 都可显示登陆人的名字, 还可以随时去查看自己的购物车中的商品, 是如何实现的?
2.也就是说, 一个用户在浏览网站不同页面时, 服务器是如何知道是张三在浏览这个页面, 还是李四在浏览这个页面?
3.如果让我们来实现这个功能, 我会如何完成?
●解决之道-session技术
1.Session是服务器端技术, 服务器在运行时为每一个用户的浏览器创建一个其独享的session对象/集合.
2.由于session为各个用户浏览器独享, 所以用户在访问服务器的不同页面时, 可以从各自的session中读取/添加数据, 从而完成相关任务.
session基本原理
session原理示意图
1.当用户打开浏览器, 访问某个网站, 操作session时, 服务器就会在内存(在服务端)为该浏览器分配一个session对象, 该session对象被这个浏览器独占.
2.这个session对象也可看作是一个容器/集合, session对象默认存在时间30min(Tomcat的conf/web.xml
中配置的), 也可修改.
session可以做什么
1.网上商城的购物车.
2.保存登陆用户的信息.
3.将数据放入到Session中, 供用户在访问不同页面时, 实现跨页面访问数据.
4.防止用户非法登录到某个页面.
如何理解Session
1.session存储结构示意图
2.你可以把session看作是一种容器类似 HashMap, 有两列(K-V), 每一行就是session的一个属性.
3.每个属性包含有两个部分, 一个是该属性的名字(String), 另一个是该属性的值(Object).
Session常用方法
1.创建和获取Session
HttpSession hs = request.getSession();
第1次调用是创建Session会话, 之后调用是获取创建好的Session对象.
2.向session添加属性
hs.setAttribute(String name, Object obj);
3.从session得到某个属性
Object obj = hs.getAttribute(String name);
4.从session删除某个属性
hs.removeAttribute(String name)
5.isNew(): 判断是不是刚创建出来的Session.
6.每个Session都有1个唯一标识Id值. 通过getId() 得到 Session的会话 id值
Session底层实现机制
原理分析图
●session底层实现机制图解
应用实例
需求: 演示session底层实现机制-创建和读取session.
代码实现
1.创建src/com/zzw/session/CreateSession.java
public class CreateSession extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.获取session, 同时也可能创建sessionHttpSession session = request.getSession();//2.获取该session的idString sessionId = session.getId();System.out.println("当前sessionId = " + sessionId);//3.给该session存放数据session.setAttribute("email", "978964140@qq.com");//4.给浏览器回复response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.print("<h1>创建并操作session成功</h1>");writer.flush();writer.close();}
}
配置web.xml
<servlet><servlet-name>CreateSession</servlet-name><servlet-class>com.zzw.session.CreateSession</servlet-class>
</servlet>
<servlet-mapping><servlet-name>CreateSession</servlet-name><url-pattern>/createSession</url-pattern>
</servlet-mapping>
2.测试session创建的机制 http://localhost:8081/cookie_session/createSession, 注意抓包分析
3.创建src/com/zzw/session/ReadSession.java
public class ReadSession extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("ReadSession doPost()...");//1.根据浏览器携带的jsessionId获取session, 如果没有对应session会创建一个HttpSession session = request.getSession();//2.输出存储在服务器端的session的idSystem.out.println("ReadSession 当前session id = " + session.getId());//3.读取当前session的属性Object email = session.getAttribute("email");if (email != null) {System.out.println("session属性 email=" + email);} else {System.out.println("session中没有email属性");}//4.回复浏览器response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.write("<h1>读取session成功</h1>");writer.flush();writer.close();}
}
<servlet><servlet-name>ReadSession</servlet-name><servlet-class>com.zzw.session.ReadSession</servlet-class>
</servlet>
<servlet-mapping><servlet-name>ReadSession</servlet-name><url-pattern>/readSession</url-pattern>
</servlet-mapping>
4.测试session创建的机制 http://localhost:8081/cookie_session/readSession, 注意抓包分析
5.有了代码的支撑, 我们再回头看session的原理图, 就有更深刻地理解.
session实现原理动画
●服务器是如何实现一个session为一个用户浏览器服务的.
Session生命周期
Session生命周期说明
1.public void setMaxInactiveInterval(int interval)
: 设置Session的超时时间(以秒为单位), 超过指定的时长, Session就会被销毁.
-
值为正数的时候, 设定Session的超时时长.
-
负数表示永不超时.
2.public int getMaxInactiveInterval()
: 获取Session的超时时间.
3.public void invalidate()
: 让当前Session会话立即无效.
4.如果没有调用setMaxInactiveInterval()
来指定Session的生命时长, Tomcat会以Session的默认时长为准, Session的默认超时时间为30min
, 可以在tomcat的web.xml中配置
5.Session的生命周期指的是: 客户端/浏览器两次请求的最大间隔时长, 而不是累积时长, 即当客户端访问了自己的session, session的生命周期将从0
开始重新计算.
6.底层: Tomcat
用一个线程来轮询会话状态, 如果某个会话的空闲时间超过设定的最大值, 则将该会话销毁.
Session生命周期实例
需求: 演示session的生命周期.
代码实现
1.创建src/com/zzw/session/CreateSession2.java
public class CreateSession2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("CreateSession2 doPost()被调用...");//1.创建sessionHttpSession session = request.getSession();System.out.println("CreateSession2 session的id为:" + session.getId());//2.设置生命周期, 即最大间隔时长为60s (60s内不访问, 删除)session.setMaxInactiveInterval(60);//3.设置属性session.setAttribute("username", "赵志伟");//4.返回给浏览器response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.write("<h1>设置session生命周期成功</h1>");writer.flush();writer.close();}
}
配置web.xml
<servlet><servlet-name>CreateSession2</servlet-name><servlet-class>com.zzw.session.CreateSession2</servlet-class>
</servlet>
<servlet-mapping><servlet-name>CreateSession2</servlet-name><url-pattern>/createSession2</url-pattern>
</servlet-mapping>
2.创建src/com/zzw/session/readSession2.java
public class ReadSession2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("ReadSession2 doPost() 被调用...");//1.获取sessionHttpSession session = request.getSession();System.out.println("ReadSession2 sessionId = " + session.getId());//2.读取session属性Object username = session.getAttribute("username");if (username != null) {System.out.println("session属性: username = " + username);} else {System.out.println("找不到username属性");}//3.返回给浏览器response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.write("读取session成功");writer.flush();writer.close();}
}
<servlet><servlet-name>ReadSession2</servlet-name><servlet-class>com.zzw.session.ReadSession2</servlet-class>
</servlet>
<servlet-mapping><servlet-name>ReadSession2</servlet-name><url-pattern>/readSession2</url-pattern>
</servlet-mapping>
3.测试. 访问createSession2后, 会在服务器创建一个只有60s的session, 如果在60s内没有浏览器没有访问, 那么在61s的时候, 浏览器携带该jsessionId访问服务器时, 服务器会再创建一个session, 并返回新的jsessionId.
如果时间没到60s, 那么访问服务器, 不会返回新的jsessionId;
如果时间超过60s, session已被销毁, 那么访问服务器, 会返回新的jsessionId.
4.创建src/com/zzw/session/DeleteSession.java
, 销毁session
public class DeleteSession extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("DeleteSession doPost() 被调用...");//1.根据浏览器jsessionId获取sessionHttpSession session = request.getSession();System.out.println("DeleteSession sessionId = " + session.getId());//2.删除session属性session.removeAttribute("username");//3.销毁sessionsession.invalidate();//因为session是在服务端的, 所以session销毁之后无需返回浏览器//3.返回给浏览器response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.write("<h1>删除session属性成功</h1>");writer.flush();writer.close();}
}
配置web.xml
<servlet><servlet-name>DeleteSession</servlet-name><servlet-class>com.zzw.session.DeleteSession</servlet-class>
</servlet>
<servlet-mapping><servlet-name>DeleteSession</servlet-name><url-pattern>/deleteSession</url-pattern>
</servlet-mapping>
5.测试. 每次访问deleteSession, 都不会返回jsessionId.
解读: Session的生命周期
1.指的是两次访问session的最大间隔时间。
2.如果你在session没有过期的情况下, 操作session, 则会重新开始计算生命周期。
3.session是否过期, 是由服务器来维护和管理
4.如果我们调用了invalidate(), 会直接将该session删除/销毁
5.如果希望删除session对象的某个属性, 使用removeAttribute(“xx”)
作业布置
需求: 防止用户非法进入管理页面.
说明
1.只要密码是666666, 我们认为就是登陆成功.
2.用户名不限制.
3.如果验证成功, 则进入管理页面 ManageServlet.Java
, 否则进入error.html
4.如果用户没有登陆过, 直接访问ManageServlet.java
, 重定向到login.html
代码实现
1.新建web/login.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>用户登录</title>
</head>
<body>
<h1>用户登陆页面</h1>
<form action="?" method="post">用户名:<input type="text" name="username" /><br/><br/>密 码:<input type="password" name="pwd" /></br><br/><input type="submit" value="登陆"/>
</form>
</body>
</html>
2.新建src/com/zzw/session/homework/ManageServlet.java
public class ManageServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpSession session = request.getSession();//1.获取登录用户名Object username = session.getAttribute("username");if (username == null) {response.sendRedirect(request.getContextPath() + "/login.html");}//2.返回给浏览器response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.write("<h1>用户管理页面</h1>\n" +"欢迎你: 管理员 " + username);writer.flush();writer.close();}
}
配置web.xml
<servlet><servlet-name>ManageServlet</servlet-name><servlet-class>com.zzw.session.homework.ManageServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>ManageServlet</servlet-name><url-pattern>/manageServlet</url-pattern>
</servlet-mapping>
3.新建web/error.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>失败页面</title>
</head>
<body>
<h1>登录失败</h1>
<a href="login.html">点击返回重新登录</a>
</body>
</html>
4.新建src/com/zzw/session/homework/LoginCheckServlet.java
public class LoginCheckServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("LoginCheckServlet doPost() 被调用...");//1.获取用户登陆数据request.setCharacterEncoding("utf-8");String password = request.getParameter("pwd");//2.校验if ("666666".equals(password)) {//如果校验成功, 获取用户名String username = request.getParameter("username");//将用户信息存入sessionHttpSession session = request.getSession();session.setAttribute("username", username);session.setAttribute("password", password);RequestDispatcher requestDispatcher = request.getRequestDispatcher("/manageServlet");requestDispatcher.forward(request, response);} else {RequestDispatcher requestDispatcher = request.getRequestDispatcher("/error.html");requestDispatcher.forward(request, response);}}
}
配置web.xml
<servlet><servlet-name>LoginCheckServlet</servlet-name><servlet-class>com.zzw.session.homework.LoginCheckServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>LoginCheckServlet</servlet-name><url-pattern>/loginCheck</url-pattern>
</servlet-mapping>
5.回填web/login.html
<form action="/cookie_session/loginCheck" method="post">
6.浏览器测试.
相关文章:

JavaWeb系列十一: Web 开发会话技术Session
Web 开发会话技术Session Session有什么用session基本原理session原理示意图session可以做什么如何理解Session Session常用方法Session底层实现机制原理分析图应用实例session实现原理动画 Session生命周期Session生命周期说明Session生命周期实例 作业布置 Session有什么用 …...

k8s中yaml文件的编写
目录 1.编写pod.yaml 2.编写deploment.yaml 3.编写service.yaml关联创建的pod 4.总结获取K8S资源配置清单文件模板方法 5.补充 1.编写pod.yaml vim demo1-pod.yaml apiVersion: v1 kind: Pod metadata:name: scj-podnamespace: xy101labels:app: nginxmylove: tangjunmyc…...

打卡第37天------动态规划
加油!不要放弃,那些冲进清北复交的高材生的水平真不是盖的,名不虚传,有实力的全能选手。我在刷题的过程中不得不表达一下对他们的钦佩。 这里在遍历顺序上可就有说法了。 如果求组合数就是外层for循环遍历物品,内层for遍历背包。如果求排列数就是外层for遍历背包,内层for…...

openfeign本地试用
目的:在本地搭建一个简单的openfeign使用场景,测试查询、新增等功能 平台:win10 技术栈:Springboot, SpringCloud, Nacos, Mybatis, MySql, Logback 框架作用说明: Nacos用于服务注册,将provider应用注…...

数据库|SQLServer数据库:查询函数(SUM、COUNT、MAX、MIN、AVG)的使用
哈喽,你好啊,我是雷工! 日拱一卒,进一寸有进一寸的欢喜,本节学习数据库查询函数的使用。 以下为学习笔记。 01 求和 SUM:对某一字段列进行求和运算; 示例: 对账号表Account的文章…...

简单Qt贪吃蛇项目
目录 先看效果 项目介绍 界面一:游戏大厅界面 界面二:关卡选择界面编辑 界面三:游戏界面 游戏大厅页面 游戏关卡选择页面 游戏房间页面 封装贪吃蛇数据结构 初始化游戏房间界面 设置窗口大小、标题、图标等 蛇的移动 初始化贪…...
画菱形(曼哈顿距离)
输入一个奇数 nn,输出一个由 * 构成的 nn 阶实心菱形。 输入格式 一个奇数 nn。 输出格式 输出一个由 * 构成的 nn 阶实心菱形。 具体格式参照输出样例。 数据范围 1≤n≤991≤n≤99 输入样例: 5输出样例: * *** ******** * #i…...
CSP初赛知识点讲解(六)
CSP初赛知识点讲解(六) 运算表达式中缀变后缀表达式求值前缀表达式 例题训练(八) 运算表达式 运算表达式有三种,前缀表达式,中缀表达式,后缀表达式,我们常用的是中缀表达式…...

linux rocky 9.2系统安装mysql-wsrep-8.4.2-26.20-linux-x86_64.tar.gz二进制包
1.环境准备, ①装好Rocky linux9.2系统,设置好IP nmcli con mod ens160 ipv4.addresses 192.168.0.106/24 nmcli con mod ens160 ipv4.gateway 192.168.0.2 nmcli con mod ens160 ipv4.dns 114.114.114.114 nmcli con up ens160 nmcli con mod ens…...
QT实现上传服务器功能
代码如下所示: void UploadZipFileToServer(const QString& strPath) {m_pFile new QFile(strPath);// 创建HTTP多部份请求QHttpMultiPart *multiPart new QHttpMultiPart(QHttpMultiPart::FormDataType);QHttpPart keyPart;keyPart.setHeader(QNetworkReques…...

元岳食堂采购供应链系统-智慧食堂数据化解决方案
随着社会的发展和科技的进步,在数字化浪潮的推动下,智慧食堂供应链系统逐渐成为食堂管理的重要工具。在此背景下,元岳食堂采购供应链系统应运而生,该系统通过其独特的数字化和自动化功能,能够对食堂的采购、储存、配送…...

基于Java+SpringBoot+Vue的影城管理系统
基于JavaSpringBootVue的影城管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 哈喽…...

自定义starter
依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 ht…...

Docker 入门全攻略:安装、操作与常用命令指南
目录 Docker 入门全攻略:安装、操作与常用命令指南 一、引言 二、Docker 下载与安装 2.1 Docker 的系统要求 2.2 安装步骤 ①对于 Windows 的安装指南 ②对于 macOS 的安装指南 ③对于 Linux 的安装指南 三、Docker 的基本概念 3.1 镜像(Image…...
mstsc被卸载,远程桌面mstsc.exe重装
官网下载地址g卸载和重新安装远程桌面连接 | Microsoft Learn 卸载和重新安装远程桌面连接 | Microsoft Learn 下载地址 https://wwm.lanzouj.com/ioR4y26z7rle 下载后重新安装...

从根儿上学习spring 十一 之run方法启动第四段(5)
图15-AbstractAutowireCapableBeanFactory#doCreateBean方法 我们接着讲doCreateBean方法,之前对循环依赖做了些解释,我们接着往下看populateBean(beanName, mbd, instanceWrapper)方法 图15-572行 这行就是调用populateBean(beanName, mbd, instanceW…...
常见8种数据结构
常见的数据结构包括数组、链表、队列、栈、树、堆、哈希表和图,每种数据结构都有其特点,如下: 常见数据结构 1.数组2.链表3.队列4.栈5.树6.图7.哈希表8.堆 1.数组 特点: 固定大小的线性数据结构支持快速随机访问插入和删除效率…...

黑马Java零基础视频教程精华部分_11_面向对象进阶(3)_抽象类、接口、适配器
《黑马Java零基础视频教程精华部分》系列文章目录 黑马Java零基础视频教程精华部分_1_JDK、JRE、字面量、JAVA运算符 黑马Java零基础视频教程精华部分_2_顺序结构、分支结构、循环结构 黑马Java零基础视频教程精华部分_3_无限循环、跳转控制语句、数组、方法 黑马Java零基础视…...

Promethues Metrics
Metrics Metrics可分为三部分: HELP 描述metric作用TYPE metric类别 TYEP Counter 某个事件发生的次数数字只能增长 Total reuqests Total ExceptionsGauge 描述当前值可以上升或下降 CurrentCPU Utilization Available System Memory Number of concurren…...
公网IP与私网IP具体有哪些区别?
1.接入方式不同 公网IP以公网连接Internet上的非保留地址,私网IP则是局域网上的IP,通过NAT才能够与公网进行通信。 2.特点不同 公网IP由国际互联网络信息中心InterNIC负责,将IP地址分配给注册并向InterNIC提出申请的机构或组织。私网IP则是为节省可分配…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...