JavaWeb学习(4)(四大域、HttpSession原理(面试)、SessionAPI、Session实现验证码功能)
目录
一、web四大域。
(1)基本介绍。
(2)RequestScope。(请求域)
(3)SessionScope。(会话域)
(4)ApplicationScope。(应用域)
(5)PageScope。(页面域)
二、HttpSession原理。
(1)Session的基本介绍。
(2)会话是什么?
1、会话的基本介绍。
2、会话的生命周期。
(3)HttpSession接口API。
1、HttpSession域对象功能。
2、HttpSession特有方法与属性。
(4)HttpSession底层原理。
1、Session的最基本特征。
2、Session底层图解。
3、Session底层解释。
4、Session自动失效与手动失效。
三、使用Session实现验证码与注销功能。
(1)前端jsp:表单项-验证码的代码。
(2)生成验证码的Servlet类。
(3)运行效果图。
(4)最终验证码的实现步骤。
1、第一次请求与响应。
2、第二次请求与响应。
3、第三次请求与响应。
4、LoginServlet类代码。
一、web四大域。
(1)基本介绍。
- 在JavaWeb开发中,"四大域"是指四种不同的作用域(scope),它们用于存储和管理用户会话中的数据。
(2)RequestScope。(请求域)
- 作用域限定在"一次请求"中。即一个Servlet处理一个客户端请求的过程中。
- 其数据存储在HttpServl
etRequest对象中。- 常用于存储一次请求中需要的数据,比如表单提交的数据。
- 使用次数:较多。
(3)SessionScope。(会话域)
- 作用域限定在"一个用户会话"中。即从用户打开浏览器到关闭浏览器的整个过程中。
- 数据存储在HttpSession对象中。
- 常用于存储用户登录状态、用户偏好设置等需要跨多个请求保持的数据。
- 使用次数:多。
(4)ApplicationScope。(应用域)
- 作用域限定在"整个Web应用程序"中。即所有用户共享。
- 数据存储在ServletContext对象ServletContext中。
- 常用于存储全局信息。(比如配置信息、应用级别的计数器等)
- 使用次数:较少。
(5)PageScope。(页面域)
- 作用域限定在"JSP页面的生命周期"内。即从JSP页面被请求到页面渲染完成的过程中。
- 数据存储在JSP页面的隐式对象pageContext中。
- 常用于存储JSP页面内的数据,比如JSP标签和脚本片段之间的数据共享。
- 使用次数:较少。
二、HttpSession原理。
(1)Session的基本介绍。
- 在JavaWeb开发中,Session通常指的是HttpSession接口。
- HttpSession是Java Servlet API提供的一个接口。
- HttpSession的对象代表了客户端与服务器端之间的一个会话。用于在客户端和服务器端之间保持状态,即跟踪用户的会话。
(2)会话是什么?
1、会话的基本介绍。
- 在Web开发中,会话(Session)是指服务器与客户端之间的一次连续的交互过程,它允许服务器跟踪和存储用户的状态信息。
- 客户端打开浏览器,访问服务器,表示会话开始。只要浏览器不关闭,本次会话一直存在。而且这次的会话的所有请求,全部共享一个Session域。(request域对象,只在用一次请求有效,作用域小)
- 当客户端关闭浏览器,表示会话的结束。
- 每一个客户端都有自己的会话。(Session)
2、会话的生命周期。
- 会话有开始和结束。
- 通常:从用户第一次与服务器交互时创建,直到用户关闭浏览器。
- 其它情况:会话超时或服务器配置的最大会话时间限制。
(3)HttpSession接口API。
- 查阅javaEE接口文档。
1、HttpSession域对象功能。
- 如下都是Session的重要方法。
- 其中有几个四大域对象都有的方法。其它的是Session域对象特有的特性与方法。
2、HttpSession特有方法与属性。
- SessionID:Session的唯一标识。
- setMaxInactiveInterval(int):最大间隔时间意思就是该Session从上一次使用到下一次使用的间隔。
- invalidate():让当前Session失效!用户的退出登录(注销)功能实现就是让当前Session域失效!
- 注销类"LogOutServlet"代码如下。
package com.fs.web;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException;/*** @Title: LoginService* @Author HeYouLong* @Package com.fs.web* @Date 2024/11/25 下午9:16* @description: 退出登录处理*/ @WebServlet("/logout") public class LogOutServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//让session失效req.getSession().invalidate();//重定向到登录界面resp.sendRedirect("/login.jsp");} }(4)HttpSession底层原理。
1、Session的最基本特征。
- 创建于服务器,保存于服务器。
- 每一个用户都有自己的Session对象。(Session不是共享的)
- 底层依赖于——Cookie实现。
2、Session底层图解。
- 服务器为每一个客户端创建Session对象时,都会生成唯一的SessionID。
- 响应给客户端时,将SessionID存储在Cookie中。注意SessionID是加密的。Cookie之后的每一次请求会自动的将SessionID发送给服务器。
- 服务器拿到SessionID进行解析并寻找对应的Session对象。
3、Session底层解释。
- Session底层是依赖Cookie的!
- 注意Session无法跨浏览器的。
- 当我首次去银行时,因为还没有账号,所以需要开一个账号,我获得的是银行卡,而银行这边的数据库中留下了我的账号,我的钱是保存在银行的账号中,而我带走的是我的卡号。
- 当我再次去银行时,只需要带上我的卡,而无需再次开一个账号了。只要带上我的卡,那么我在银行操作的一定是我的账号!
- 当首次使用Session时,服务器端要创建Session对象。Session是保存在服务器端,而给客户端的是SessionID(一个cookie中保存SessionID)。客户端带走的是SessionID,而数据是保存在Session对象中。
- 当客户端再次访问服务器时,在请求中会带上SessionID。而服务器会通过SessionID找到对应的Session对象,而无需再创建新的Session对象。
4、Session自动失效与手动失效。
- 开发人员可以通过调用Session对象的的invalidate()方法来手动使Session失效。这通常在用户注销或退出登录时使用。
- Session对象会有一个默认的超时时间,如果用户在这段时间内没有任何操作,Session将会自动失效。
当服务器重启或重启应用时,所有的Session对象都会被销毁,导致所有用户的Session失效。或者关闭浏览器通常也会导致Session失效。
三、使用Session实现验证码与注销功能。
(1)前端jsp:表单项-验证码的代码。
- 注意生成验证码图片的功能是通过代码完成。(访问指定的"/XXXServlet")
- 注意:css样式使用的是bootstrap提供的样式与组件。通过<link>标签在线引入。
<div class="form-inline"><label for="vcode">验证码:</label><input type="text" name="verifycode" class="form-control" id="verifycode" placeholder="请输入验证码" style="width: 120px;"/><a href="javascript:refreshCode()"><img src="/checkCode" title="看不清点击刷新" id="vcode"/></a></div>
- 刷新验证码时,触发点击事件,调用方法refreshCode()。代码如下。
<script type="text/javascript">//js定义函数function refreshCode(){//不做下面处理,就会走浏览器缓存, url没有变化, 导致使用上一次缓存内容,不会刷新验证码//选择器 #id名——>获取到img标签//使用attr()设置属性"src"值。//加一个时间戳, 每次都不一样, 浏览器发现参数不一样, 误以为是新请求,不走缓存,就会刷新$("#vcode").attr("src","/checkCode?"+new Date().getTime());}</script>(2)生成验证码的Servlet类。
package com.fs.web;import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** 验证码*/ @WebServlet("/checkCode") public class CheckCodeServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//服务器通知浏览器不要缓存response.setHeader("pragma","no-cache");response.setHeader("cache-control","no-cache");response.setHeader("expires","0");//在内存中创建一个长80,宽30的图片,默认黑色背景//参数一:长//参数二:宽//参数三:颜色int width = 80;int height = 30;BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//获取画笔Graphics g = image.getGraphics();//设置画笔颜色为灰色g.setColor(Color.GRAY);//填充图片g.fillRect(0,0, width,height);//产生4个随机验证码,12EyString checkCode = getCheckCode();//将验证码放入HttpSession中。//这里很重要,因为登录请求时,需要拿取服务器生成的验证码与用户输入的验证码进行校验!request.getSession().setAttribute("CHECKCODE_SERVER",checkCode);//设置画笔颜色为黄色g.setColor(Color.YELLOW);//设置字体的小大g.setFont(new Font("黑体",Font.BOLD,24));//向图片上写入验证码g.drawString(checkCode,15,25);//将内存中的图片输出到浏览器//参数一:图片对象//参数二:图片的格式,如PNG,JPG,GIF//参数三:图片输出到哪里去ImageIO.write(image,"PNG",response.getOutputStream());}/*** 产生4位随机字符串 */private String getCheckCode() {String base = "0123456789ABCDEFGabcdefg";int size = base.length();Random r = new Random();StringBuffer sb = new StringBuffer();for(int i=1;i<=4;i++){//产生0到size-1的随机值int index = r.nextInt(size);//在base字符串中获取下标为index的字符char c = base.charAt(index);//将c放入到StringBuffer中去sb.append(c);}return sb.toString();}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request,response);} }(3)运行效果图。
(4)最终验证码的实现步骤。
1、第一次请求与响应。
- 第一次请求:客户端请求login.jsp(登录页面)。
- 服务器第一次响应。在客户端显示login.jsp(登录页面)。
2、第二次请求与响应。
- 第二次请求"XXXServlet":请求客户端登录界面中的随机验证码图片。
- 服务器第二次响应。并将生成的随机验证码存储在Session域中。
- 为什么验证码不存储在Cookie中?不安全、无意义。因为Cookie暴露在客户端,用户可以查看和修改!
- 随后在登录界面的验证码位置显示生成的验证码图片。
3、第三次请求与响应。
- 第三次请求:用户在客户端填写(用户名、密码、验证码等)后,点击提交"登录"按钮。也就是登录请求。("/LoginServlet")
- 服务器处理请求。首先判断验证码是否正确!!
- 如何校验用户输入的验证码与服务器响应的验证码一致?
- 在第二次请求与响应中,服务器将生成的随机验证码存储在Session中。因为验证码每生成一次就不能让用户去更改,所以存储在服务器(域对象),而不是存储在客户端
- 使用Session技术!而不使用Request域。是因为不是同一次请求,拿不到数据。
- 通过会话(Session)技术可以实现该功能。
- 第三次请求服务器拿到用户提交的验证码与Session域获取到的验证码进行比对即可。
- 通过HttpServletRequest对象的getSession()方法获取到HttpSession对象。
- 再通过HttpSession对象的getAttribute("键名")得到对应的键值(验证码)即可。
4、LoginServlet类代码。
- 其中涉及到"记住我"功能的实现。(使用Cookie技术)
package com.fs.web;import com.fs.entity.LoginInfo; import com.fs.service.LoginService; import com.fs.service.impl.LoginServiceImpl;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; import java.util.Objects;/*** @Title: LoginService* @Author HeYouLong* @Package com.fs.web* @Date 2024/11/25 下午9:16* @description: 登录处理*/ @WebServlet("/login") public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.设置post请求编码, 响应编码req.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");//进行验证码验证//获取用户输入的验证码String verifycode = req.getParameter("verifycode");//获取服务器发来的验证码。与session存的验证码比对HttpSession session = req.getSession();String codeServer = (String) session.getAttribute("CHECKCODE_SERVER");if (codeServer.equals(verifycode)) {//2.获取请求参数String username = req.getParameter("user");String password = req.getParameter("password");//3.调用业务层LoginService的登录方法LoginService loginService = new LoginServiceImpl();LoginInfo loginInfo = loginService.login(username, password);//4.根据返回结果跳转到不同的资源if (loginInfo != null) { //登录成功//判断是否勾选记住我String rem = req.getParameter("rem");if (Objects.nonNull(rem)) {//设置CookieCookie cookie1 = new Cookie("user", username);Cookie cookie2 = new Cookie("password", password);//设置存活时间(单位:秒)//7天cookie1.setMaxAge(60 * 60 * 24 * 7);cookie2.setMaxAge(60 * 60 * 24 * 7);//设置path为/ 项目下任何资源可以访问cookie1.setPath("/");cookie2.setPath("/");//发送Cookieresp.addCookie(cookie1);resp.addCookie(cookie2);}//跳转之前把LoginInfo对象保存到session域中session.setAttribute("loginUser",loginInfo);//重定向到index.html页面resp.sendRedirect("/index.jsp");} else { //登录失败//转发到登录页面req.setAttribute("error", "账号或密码错误!");req.getRequestDispatcher("/login.jsp").forward(req, resp);}} else { //验证码错误req.setAttribute("error", "验证码输入错误!");req.getRequestDispatcher("/login.jsp").forward(req, resp);}} }
相关文章:
JavaWeb学习(4)(四大域、HttpSession原理(面试)、SessionAPI、Session实现验证码功能)
目录 一、web四大域。 (1)基本介绍。 (2)RequestScope。(请求域) (3)SessionScope。(会话域) (4)ApplicationScope。(应用域) (5)PageScope。(页面域) 二、Ht…...
Ubuntu22.04系统源码编译OpenCV 4.10.0(包含opencv_contrib)
因项目需要使用不同版本的OpenCV,而本地的Ubuntu22.04系统装了ROS2自带OpenCV 4.5.4的版本,于是编译一个OpenCV 4.10.0(带opencv_contrib)版本,给特定的项目使用,这就不用换个设备后重新安装OpenCV 了&…...
【Unity高级】在编辑器中如何让物体围绕一个点旋转固定角度
本文介绍如何在编辑器里让物体围绕一个点旋转固定角度,比如上图里的Cube是围绕白色圆盘的中心旋转45度的。 目标: 创建一个在 Unity 编辑器中使用的旋转工具,使开发者能够在编辑模式下快速旋转一个物体。 实现思路: 编辑模式下…...
2024.11.29——[HCTF 2018]WarmUp 1
拿到题,发现是一张图,查看源代码发现了被注释掉的提示 <!-- source.php--> step 1 在url传参看看这个文件,发现了这道题的源码 step 2 开始审计代码,分析关键函数 //mb_strpos($haystack,$needle,$offset,$encoding):int|…...
AGameModeBase和游戏模式方法
AGameModeBase和游戏模式方法有着密切的关系: AGameModeBase是游戏模式的基础类: 它提供了控制游戏规则的基本框架包含了一系列管理游戏流程的核心方法是所有自定义游戏模式类的父类 主要的游戏模式方法包括: // 游戏初始化时调用 virtua…...
Swift 扩展
Swift 扩展 Swift 是一种强大的编程语言,由苹果公司开发,用于iOS、macOS、watchOS和tvOS应用程序的开发。自2014年发布以来,Swift因其易于阅读和编写的语法、现代化的设计以及出色的性能而广受欢迎。本文将探讨Swift的一些关键特性ÿ…...
【NebulaGraph】官方查询语言nGQL教程1 (四)
【NebulaGraph】官方查询语言nGQL教程1 1. 课程信息2. 查找路径FIND PATH2.1 补充说明FIND PATH2.2 例子 1. 课程信息 课程地址: https://www.bilibili.com/video/BV1PT411P7w8/?spm_id_from333.337.search-card.all.click&vd_source240d9002f7c7e3da63cd9a975639409a …...
阿里云负载均衡SLB实践
基于上篇文章继续,如果你使用的是阿里云等云平台,通过配置nginxkeepAlived行不通,因为阿里云服务器不支持你虚拟出ip提供给外部访问,需要使用阿里云的负载均衡产品 对应的产品有三个系列 1、应用场景 ALB: 主要是对应应用层的7层…...
鸿蒙技术分享:❓❓[鸿蒙应用开发]怎么更好的管理模块生命周期?
鸿蒙HarmonyOS NEXT应用开发架构设计-模块生命周期管理 模块化开发 模块化开发已经是应用开发中的一个共识,一般对于公司级的应用开发,都会考虑是否可以进行模块化开发。 HarmonyOS NEXT系统应用开发目前使用的Stage模型其实就有涉及模块化开发的部分…...
深度解析 Ansible:核心组件、配置、Playbook 全流程与 YAML 奥秘(上)
文章目录 一、ansible的主要组成部分二、安装三、相关文件四、ansible配置文件五、ansible 系列 一、ansible的主要组成部分 ansible playbook:任务剧本(任务集),编排定义ansible任务集的配置文件,由ansible顺序依次执…...
LabVIEW气缸摩擦力测试系统
基于LabVIEW的气缸摩擦力测试系统实现了气缸在不同工作状态下摩擦力的快速、准确测试。系统由硬件平台和软件两大部分组成,具有高自动化、精确测量和用户友好等特点,可广泛应用于精密机械和自动化领域。 项目背景: 气缸作为舵机关键部件…...
Leetcode. 688骑士在棋盘上的概率
题目描述 原题链接:Leetcode. 688骑士在棋盘上的概率 解题思路 多元dp 将dp[step][i][j])定义为从(i, j)出发,走step步之后骑士还在棋盘上的概率。 如果 ( i , j ) (i,j) (i,j)不在棋盘上,即非 0 < i < n 0<i<n 0<i<…...
TCP/IP 协议栈高效可靠的数据传输机制——以 Linux 4.19 内核为例
TCP/IP 协议栈是一种非常成熟且广泛使用的网络通信框架,它将复杂的网络通信任务分成多个层次,从而简化设计,使每一层的功能更加清晰和独立。在经典的 TCP/IP 协议栈中,常见的分层为链路层、网络层、传输层和应用层。本文将对每一层的基本功能进行描述,并列出对应于 Linux …...
Ubuntu22.04搭建LAMP环境(linux服务器学习笔记)
目录 引言: 一、系统更新 二、安装搭建Apache2 1.你可以通过以下命令安装它: 2.查看Apache2版本 3.查看Apache2运行状态 4.浏览器访问 三、安装搭建MySQL 1.安装MySQL 2.查看MySQL 版本 3.安全配置MySQL 3.1是否设置密码?(按y|Y表…...
鸿蒙面试---1208
HarmonyOS 三大技术理念 分布式架构:HarmonyOS 的分布式架构使得设备之间能够无缝协同工作。例如,它允许用户在不同的智能设备(如手机、平板、智能手表等)之间共享数据和功能。比如,用户可以在手机上开始编辑文档&…...
java基础教程第16篇( 正则表达式)
Java 正则表达式 正则表达式定义了字符串的模式。 正则表达式可以用来搜索、编辑或处理文本。 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。 Java 提供了 java.util.regex 包,它包含了 Pattern 和 Matcher 类,用于处理正…...
Docker部署的gitlab升级的详细步骤(升级到17.6.1版本)
文章目录 一、Gitlab提示升级信息二、老版本的docker运行gitlab命令三、备份老版本Gitlab数据四、确定升级路线五、升级(共分3个版本升级)5.1 升级第一步(17.1.2 > 17.3.7)5.2 升级第二步(17.3.7 > 17.5.3)5.3 升级第三步(17.5.3 > 17.6.1) 六、web端访问gitlab服务 一…...
【如何制定虚拟货币的补仓策略并计算回本和盈利】
在虚拟货币市场中,价格波动性极大,如何在波动中生存并获得盈利是每个投资者都在思考的问题。作为一种投资策略,补仓(又称“摊低成本”)常常被用来降低持仓成本,并在市场回升时获得更大的盈利。但如何科学地设定补仓计划,确定回本点和盈利目标呢? 本文将以 Dogecoin 为…...
给图像去除水印攻
去除水印的过程与添加水印相反,它涉及到图像修复、颜色匹配和区域填充等技术。OpenCV-Python 提供了多种方法来处理不同类型的水印,包括但不限于纯色水印、半透明水印以及复杂背景上的水印。下面将详细介绍几种常见的去水印策略,并给出具体的…...
Linux之封装线程库和线程的互斥
Linux之封装线程库和线程的互斥与同步 一.封装线程库二.线程的互斥2.1互斥量的概念2.2初始化和销毁互斥量2.3加锁和解锁2.4互斥量的原理2.5可重入和线程安全2.6死锁 一.封装线程库 其实在我们C内部也有一个线程库而C中的线程库也是封装的原生线程库的函数,所以我们…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
Mac flutter环境搭建
一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...









