当前位置: 首页 > news >正文

Java Web 核心进阶:会话跟踪与Servlet配置实战

在上一篇内容中,我们已经掌握了Java Web的基础框架——Tomcat容器的核心目录与部署方式,以及Servlet的核心原理、请求响应对象的使用。本节课我们将进入进阶环节,聚焦会话跟踪技术(Cookie与Session)、Servlet的配置对象(ServletContext与ServletConfig),并通过一个完整的登录实战案例,将所有知识点串联起来,帮你真正做到学以致用,理解Java Web请求处理与数据管理的底层逻辑。

三、Cookie:客户端会话跟踪技术

3.1 Cookie 核心概念

Cookie是**存储在客户端(浏览器)的键值对数据**,由服务器生成,通过响应头发送给浏览器,浏览器下次请求时会携带Cookie,实现会话跟踪(如记住登录状态、记录上次访问时间)。

简单来说,Cookie就相当于服务器给浏览器的“身份标签”,浏览器每次访问该服务器时,都会带上这个标签,让服务器识别出当前访问的是哪个用户,从而实现状态保持——毕竟HTTP协议本身是无状态的,无法记住每次请求的关联关系,Cookie正是解决这一问题的客户端方案。

3.2 Cookie 核心操作

1. 创建Cookie
// 创建Cookie,参数:key、value Cookie lastTimeCookie = new Cookie("lastVisitTime", "2026-03-30 14:35:56"); Cookie loginTimeCookie = new Cookie("loginTime", "2026-03-25 15:25:25"); Cookie usernameCookie = new Cookie("username", "damin"); // 把Cookie添加到响应,发送给浏览器 resp.addCookie(lastTimeCookie); resp.addCookie(loginTimeCookie); resp.addCookie(usernameCookie);
2. 获取Cookie
// 从请求中获取所有Cookie Cookie[] cookies = req.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { String name = cookie.getName(); // 获取Cookie的key String value = cookie.getValue(); // 获取Cookie的value System.out.println(name + ": " + value); } }
3. 修改Cookie

Cookie没有专门的修改方法,**同名Cookie会覆盖旧值**,只需创建同名Cookie并设置新值,重新添加到响应中即可覆盖原有Cookie:

// 创建同名Cookie,设置新值 Cookie lastTimeCookie = new Cookie("lastVisitTime", "2026-04-03 10:00:00"); // 重新添加到响应,覆盖旧Cookie resp.addCookie(lastTimeCookie);
4. 设置Cookie有效期

Cookie默认是**会话级Cookie**(浏览器关闭就删除),可以通过`setMaxAge`方法设置有效期,单位为秒:

Cookie cookie = new Cookie("username", "damin"); // 设置有效期:30天 = 30*24*60*60 = 2592000秒 cookie.setMaxAge(2592000); // 补充说明:0表示立即删除Cookie;-1表示会话级(默认值) resp.addCookie(cookie);

补充:Cookie 的限制:

  • 大小限制:单个 Cookie 最大 4KB
  • 数量限制:每个域名最多 50 个 Cookie
  • 安全性:Cookie 存储在客户端,不可存储敏感信息(如密码)

四、Session:服务器端会话跟踪技术

4.1 Session 核心概念

Session是**存储在服务器端的会话对象**,每个浏览器对应一个Session,通过`SessionID`标识(SessionID会自动存储在客户端的Cookie中),用来在服务器端保存用户敏感数据(如登录状态、用户信息)。

与Cookie存储在客户端不同,Session的数据全部存放在服务器,安全性更高,且没有大小限制,是处理用户敏感信息的核心方案。当浏览器第一次访问服务器时,服务器会创建一个Session,并生成唯一的SessionID,通过Cookie发送给浏览器;后续浏览器访问时,会携带SessionID,服务器通过该ID找到对应的Session,从而获取用户的会话数据。

4.2 Session 核心操作

1. 获取Session对象
// 获取Session,不存在则创建新的(常用方式) HttpSession session = req.getSession(); // 获取SessionID(唯一标识当前会话) String sessionId = session.getId();

补充:`req.getSession(false)` 表示:若Session不存在,不创建新Session,直接返回null。

2. 向Session存数据
// 存储用户数据到Session(键值对形式,值为Object类型) session.setAttribute("username", "damin"); session.setAttribute("pwd", "123456"); session.setAttribute("userRole", "admin"); // 可存储任意对象
3. 从Session取数据
// 获取Session对象 HttpSession session = req.getSession(); // 读取数据,需强制转换类型(因为存的是Object) String username = (String) session.getAttribute("username"); String pwd = (String) session.getAttribute("pwd"); String userRole = (String) session.getAttribute("userRole");
4. Session 销毁

Session有两种销毁方式:手动销毁(如用户退出登录)和自动超时销毁(服务器默认配置):

// 1. 手动销毁Session(如退出登录功能) session.invalidate(); // 2. 设置Session超时时间(单位秒,默认30分钟) session.setMaxInactiveInterval(1800); // 30分钟,无操作则自动销毁

4.3 Cookie vs Session 核心区别

特性

Cookie

Session

存储位置

客户端(浏览器)

服务器端

安全性

低(可被篡改、窃取)

高(数据在服务器,不可直接访问)

存储大小

小(单个4KB限制)

大(无严格限制,取决于服务器内存)

生命周期

可自定义(会话级/持久化)

默认30分钟,可手动销毁或设置超时

适用场景

非敏感数据(如上次访问时间、记住用户名)

敏感数据(如登录状态、用户权限、用户信息)

五、ServletContext 与 ServletConfig:Servlet 的配置对象

在Servlet开发中,除了请求响应对象、会话对象,还有两个核心配置对象——ServletContext和ServletConfig,它们分别负责全局配置和局部配置,是实现Servlet参数管理、数据共享的关键工具,很多初学者容易混淆两者的作用,下面我们逐一拆解。

5.1 ServletContext:全局上下文对象

核心定义

每个Web应用(项目)在服务器启动时,会创建一个唯一的`ServletContext`对象,它是**全局共享对象**,整个项目中的所有Servlet、JSP都能访问它,主要用于存储全局参数、实现Servlet间的数据共享,以及获取项目相关的资源信息。

核心操作
// 1. 获取ServletContext对象(三种常用方式,效果一致) ServletContext context1 = this.getServletContext(); ServletContext context2 = req.getServletContext(); ServletContext context3 = session.getServletContext(); // 2. 设置全局共享数据(所有Servlet都能访问) context1.setAttribute("totalVisit", 5); // 统计总访问量,全局共享 // 3. 获取全局共享数据 Integer totalVisit = (Integer) context1.getAttribute("totalVisit"); resp.getWriter().write("总访问量:" + totalVisit); // 4. 获取web.xml中配置的全局初始化参数(需在web.xml中配置) String url = context1.getInitParameter("jdbcUrl");
web.xml 全局参数配置示例
<!-- 全局初始化参数(所有Servlet共享) --> <context-param> <param-name>jdbcUrl</param-name> <param-value>jdbc:mysql://localhost:3306/mydb</param-value> </context-param><context-param> <param-name>driverClass</param-name> <param-value>com.mysql.cj.jdbc.Driver</param-value> </context-param>

5.2 ServletConfig:Servlet专属配置对象

核心定义

`ServletConfig`是**局部配置对象**,每个Servlet在创建时,都会对应一个专属的ServletConfig对象,仅当前Servlet能访问,主要用于存储当前Servlet的专属初始化参数,实现单个Servlet的个性化配置。

核心操作
1. 重写init方法,获取ServletConfig
private ServletConfig sc; // 重写init方法,获取当前Servlet的ServletConfig对象 @Override public void init(ServletConfig config) throws ServletException { this.sc = config; // 保存ServletConfig对象,供后续使用 }
2. web.xml中配置Servlet初始化参数
<servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.example.unit2_11.MyServlet</servlet-class> <!-- 配置当前Servlet的专属初始化参数(仅当前Servlet可用) --> <init-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mydb</param-value> </init-param> <init-param> <param-name>username</param-name> <param-value>root</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>12345678</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/MyServlet</url-pattern> </servlet-mapping>
3. 在Servlet中获取初始化参数
// 获取ServletConfig中配置的专属参数 String url = sc.getInitParameter("url"); String username = sc.getInitParameter("username"); String password = sc.getInitParameter("password"); // 输出参数,用于后续数据库连接等操作 System.out.println("数据库地址:" + url); System.out.println("数据库用户名:" + username);

5.3 ServletContext vs ServletConfig 核心区别

特性

ServletContext

ServletConfig

作用范围

全局,整个Web应用(所有Servlet共享)

局部,仅当前Servlet可用

对象数量

一个Web应用只有一个

每个Servlet对应一个

配置位置

web.xml中<context-param>标签

web.xml中<servlet>标签内的<init-param>标签

核心用途

全局数据共享、获取全局配置、访问项目资源

当前Servlet的专属配置、个性化参数设置

六、实战:完整 Servlet 登录案例

结合前面所学的Cookie、Session、ServletConfig、请求响应对象等知识点,我们编写一个完整的Servlet登录案例,模拟用户登录校验、状态保持、页面跳转的完整流程,帮助大家巩固所学,理解知识点的实际应用场景。

案例需求:用户提交用户名和密码,服务器校验通过后,将用户信息存入Session,用Cookie记住用户名(7天有效期),重定向到首页;校验失败则返回登录页,显示错误提示。

6.1 登录Servlet完整代码

@WebServlet("/login") // 注解配置URL映射 public class LoginServlet extends HttpServlet { // 模拟数据库中的用户名和密码(实际开发中从数据库查询) private static final String DB_USERNAME = "damin"; private static final String DB_PASSWORD = "123456"; @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 设置请求和响应编码,解决中文乱码问题 req.setCharacterEncoding("UTF-8"); // 处理请求参数中文乱码 resp.setContentType("text/html;charset=utf-8"); // 处理响应中文乱码 // 2. 获取客户端提交的请求参数(用户名、密码) String username = req.getParameter("username"); String password = req.getParameter("password"); // 3. 模拟数据库校验(对比提交的参数与模拟数据) if (DB_USERNAME.equals(username) && DB_PASSWORD.equals(password)) { // 4. 登录成功:存储用户信息到Session,保持登录状态 HttpSession session = req.getSession(); session.setAttribute("username", username); // 存入用户名 session.setAttribute("loginStatus", true); // 存入登录状态 // 5. 创建Cookie,记住用户名(有效期7天) Cookie usernameCookie = new Cookie("username", username); usernameCookie.setMaxAge(7 * 24 * 60 * 60); // 7天 = 604800秒 resp.addCookie(usernameCookie); // 发送Cookie到浏览器 // 6. 重定向到首页(避免表单重复提交,地址栏改变) resp.sendRedirect("/index.jsp"); } else { // 7. 登录失败:存储错误提示到request域,转发到登录页 req.setAttribute("msg", "用户名或密码错误,请重新登录!"); // 转发到登录页,地址栏不变,可共享request域中的错误信息 req.getRequestDispatcher("/login.jsp").forward(req, resp); } } // 统一处理GET请求(将GET请求转发到POST方法,避免重复代码) @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }

6.2 案例核心知识点应用说明

  • 请求编码设置:`req.setCharacterEncoding("UTF-8")` 解决POST请求参数中文乱码问题;

  • Session应用:存储用户登录状态和用户名,确保用户在会话期间无需重复登录;

  • Cookie应用:记住用户名,下次访问登录页时可自动填充(需在JSP页面配合获取Cookie);

  • 转发与重定向:失败用转发(共享错误信息),成功用重定向(避免表单重复提交);

  • 注解配置:`@WebServlet("/login")` 简化配置,无需编写web.xml映射。

6.3 补充:登录页(login.jsp)简化代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %> 用户登录用户登录<!-- 显示错误提示(登录失败时从request域获取) --> <% String msg = (String) request.getAttribute("msg"); %> <% if (msg != null) { %> <font color="red"><%= msg %></font> <% } %> <!-- 表单提交到/login Servlet -->

七、本模块总结

本模块我们聚焦Java Web的进阶核心知识点,从会话跟踪技术到Servlet配置对象,再到实战案例,完整覆盖了“数据存储-参数配置-实际应用”的核心流程,核心要点总结如下:

  1. 会话跟踪:Cookie(客户端存储,非敏感数据)和Session(服务器存储,敏感数据)是解决HTTP无状态问题的核心方案,两者配合使用,既能实现状态保持,又能保证数据安全,需牢记两者的区别与适用场景。

  2. Servlet配置对象:ServletContext(全局共享,管理全局参数和资源)和ServletConfig(局部专属,配置单个Servlet参数),明确两者的作用范围和使用场景,避免混淆。

  3. 实战核心:请求响应对象、Cookie、Session、转发/重定向的综合应用,是Java Web开发的基础能力,登录案例完整演示了这些知识点的联动,掌握该案例,就能应对简单的Web交互场景。

至此,Java Web的核心基础知识点(Tomcat、Servlet、会话跟踪、配置对象)已全部讲解完毕,这些知识点是后续学习Filter、Listener、SpringMVC等框架的底层基础,建议多动手编写代码,熟练掌握各对象的核心操作,真正做到融会贯通。

http://www.jsqmd.com/news/605331/

相关文章:

  • MacBook高效办公:OpenClaw+Phi-3-vision-128k-instruct自动化实践
  • 星图GPU云体验OpenClaw:免安装调试Phi-3-mini-128k-instruct镜像
  • 电子python模拟出的一个完美风暴
  • OpenClaw+百川量化模型:个人公众号自动化排版发布实战
  • 2026年静音跑步机专业排行:微云跑步机/静音跑步机/家用跑步机/小型跑步机/减震跑步机/跑步机/选择指南 - 优质品牌商家
  • ZeroTermux中的Mysql
  • 从IMX290光谱曲线到红绿灯变色:聊聊监控摄像头ISP里那个神奇的CCM矩阵
  • 2026年mpa培训好不好:mpa笔试培训/mpa辅导/在职考研管综初试培训/在职考研管综初试辅导/选择指南 - 优质品牌商家
  • FPGA图像处理避坑指南:实现CLAHE时,你的直方图统计与插值模块可能踩的这些雷
  • CSS如何处理绝对定位引起的遮挡问题_调整z-index与层级管理
  • SQL窗口函数完整指南:5大高频场景详细代码注释(面试必备)
  • H-PPO: Advancing Hybrid Reinforcement Learning in Parameterized Action Spaces with Proximal Policy O
  • 别再瞎调参了!HuggingFace Trainer微调BERT/ViT的保姆级避坑指南(附ArcFace实战代码)
  • 工业质检新利器:手把手搭建M3DM环境(含CUDA KNN、PointNet2避坑指南)
  • OpenClaw技能市场探秘:Qwen3.5-9B-AWQ-4bit十佳实用技能推荐
  • LoRaWAN网关能传多远
  • 解决Deformable-DETR报错:ms_deformable_im2col_cuda找不到kernel image的终极指南(附CUDA路径配置技巧)
  • 别只盯着0x10发请求:深入理解UDS 10服务背后的会话管理机制与安全设计
  • 2026四川单招短期冲刺集训机构深度评测 - 优质品牌商家
  • 清风输入法(
  • 5分钟搞定FPGA原理图库:从XILINX官方文档到AD软件的全流程解析
  • 树莓派5硬件PWM驱动舵机实战:从设备树编译到精准角度控制
  • 蓝卓总裁陈玉龙:从数据底座到智能大脑,拆解supOS平台进化三部曲
  • OpenClaw+千问3.5-27B创作助手:从大纲到公众号全自动
  • 微信小程序物流查询插件接入全攻略:从资质申请到waybill_token获取(附完整代码)
  • seo 排名优化外包流程是怎样的
  • UID 转换 11 位线索
  • 深入解析CSAPP ArchLab:Y86汇编优化实战指南
  • CPython内存分配器深度解剖,从PyMalloc到Arena分级管理,97%开发者从未启用的3项安全加固开关
  • 2026数字车钥匙使用指南:3大痛点解决,车主必看!