Cookie , Session 与 ServletContext

Cookie对象

在 Servlet 中,Cookie​ 是用于在客户端(浏览器)存储少量数据的一种机制,常用于会话管理、用户偏好设置等场景
(会话管理用于跟踪用户在网站中的状态(如登录状态、购物车内容)。)
(用户偏好设置存储用户的个性化配置(如语言、主题颜色、时区))

Crtl +左键 可以查看源码
在这里插入图片描述

Cookie的创建与发送

创建
  • 服务器创建 Cookie:Servlet 通过 response.addCookie() 向客户端发送 Cookie。
Cookie cookie = new Cookie("name", "admin");
resp.addCookie(cookie);
  • 浏览器在向服务器发送请求时,会自动检查当前域名和路径下的 Cookie
  • 如果存在符合条件的 Cookie(未过期、路径匹配、域名匹配等),浏览器会将这些 Cookie 添加到请求头的 Cookie 字段中

例如:

GET /your-servlet-path HTTP/1.1
Cookie: name=admin; sessionId=abc123
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
    // 创建 Cookie 对象  
    Cookie cookie = new Cookie("name", "admin");  
    // 将 Cookie 添加到响应  
    resp.addCookie(cookie);  
}

![[Pasted image 20250304222604.png]]

接受
  • 客户端存储 Cookie:浏览器保存 Cookie(键值对),并在后续请求中自动携带(通过 request.getCookies() 读取)[就算服务器关了,只要没有失效,cookie会一直存在浏览器]
GET /your-servlet-path HTTP/1.1
Cookie: name=admin; sessionId=abc123
  • Servlet 容器(如 Tomcat)会解析请求头中的 Cookie 字段
  • 将 Cookie 数据转换为 javax.servlet.http.Cookie 对象数组,可通过 request.getCookies() 获取
Cookie[] cookies = req.getCookies();
if (cookies != null&& cookies.length > 0){	
  for (Cookie c : cookies) {
	System.out.println(c.getName() + ": " + c.getValue());
    }
}
     

![[Pasted image 20250304232220.png]]

Cookie的的有效期

默认当前的浏览器关闭失效.但我们可以手动设定cookie的有效时间,
在 Servlet 中,Cookie 的到期时间(Expiration)​​ 由 setMaxAge(int seconds) 方法控制

到期时间的取值
正数在指定秒数后过期, Cookie 持久化到客户端硬盘,
负数浏览器关闭时自动删除(默认行为)。
0立即删除 Cookie(需保证 namepathdomain 与原 Cookie 一致)。


/* 到期时间:负整数 (默认值-1,表示只有在浏览器内存中存活,关闭浏览器失效*/ 
Cookie cookie = new Cookie("cookie", "cookie");  
cookie.setMaxAge(-1);  
resp.addCookie(cookie);  
  
/*到期时间: 正整数 (表示存活指定秒数,会将数据存在磁盘中)*/  
// 创建 Cookie 对象
Cookie cookie2 = new Cookie("cookie2", "cookie2");  
// 设置有效期(单位:秒)
cookie2.setMaxAge(30); //存活30s 
resp.addCookie(cookie2);  
  
/*到期时间: 零 (表示删除cookie) */  
Cookie cookie3 = new Cookie("cookie3", "cookie3");  
// 删除 Cookie
cookie3.setMaxAge(0);  
resp.addCookie(cookie3);

访问cookie03 cookie3已经删除
![[Pasted image 20250305192804.png]]

关闭浏览器 再访问cookie02 cookie失效
![[Pasted image 20250305193222.png]]

场景设置方法示例
用户登录保持setMaxAge(7 * 24 * 3600)记住登录状态 7 天
临时会话数据setMaxAge(-1)(默认)购物车临时数据
强制退出登录setMaxAge(0)删除登录凭证 Cookie
用户行为跟踪setMaxAge(365 * 24 * 3600)长期统计用户偏好

Cookie 路径

一、Cookie 路径的作用

通过 setPath() 方法设置 Cookie 的路径,可以控制该 Cookie 在哪些请求路径下会被浏览器发送到服务器。路径匹配规则基于请求的 URL 路径。

二、不同情景的代码示例与解释

情景一:服务器下所有项目共享 Cookie
域名下所有路径

// 当前项目路径为 S01
Cookie cookie = new Cookie("key", "value"); 
//当前服务器(域名)下的所有项目均可访问此 Cookie
cookie.setPath("/");  // 设置路径为根路径
response.addCookie(cookie);  

当前服务器(域名)下的所有项目均可访问此 Cookie

情景二:仅当前项目内共享 Cookie(默认行为)
当前项目及其子路径

// 当前项目路径为 S01
Cookie cookie = new Cookie("key", "value");  
// 设置路径为"/s01",表示当前项目下任何项目都可以访问到Cookie对象
cookie.setPath("/S01");  // 默认行为,可省略此设置
response.addCookie(cookie);  
效果:

Cookie 的路径为 /S01,仅当访问 当前项目(S01)及其子路径 时才会发送 Cookie。

情景三:指定其他项目共享 Cookie
指定项目及其子路径

// 当前项目路径为 S01
Cookie cookie = new Cookie("key", "value");  
cookie.setPath("/S02");  // 即使cookie是s01产生的,s01也不能获得它,只能在s02中获取
response.addCookie(cookie);  

只能在s02中获取

情景四:子路径共享 Cookie
特定子路径及其下级路径

// 当前项目路径为 S01
Cookie cookie = new Cookie("key", "value");  
cookie.setPath("/S01/sub");  // 只有在/S01/sub目录下才可以访问到Cookie对象
response.addCookie(cookie);  

只有在/S01/sub目录下才可以访问

注意

Cookie 的存储范围限制

不能跨浏览器:Cookie 仅保存在当前浏览器中

不能跨域:Cookie 默认绑定到创建它的域名和路径(可通过 Domain 和 Path 属性调整

匹配规则:

域名(domain):

  • 默认绑定到当前域名如 www.example.com)。
  • 显式设置可共享到子域名
cookie.setDomain(".example.com"); // 子域名(如api.example.com)可访问

路径(path):

  • 默认绑定到当前路径(如 /app)。
  • 若设置 cookie.setPath(“/”),则所有路径均可访问。
cookie.setPath("/"); // 所有路径均可访问

有效期:
会话级 Cookie:不设置 maxAge,浏览器关闭后失效。
持久化 Cookie:设置 maxAge,长期有效直至过期。
跨域限制:
Cookie 不能跨浏览器
不能跨域发送(除非通过 CORS 策略显式允许且设置 withCredentials)。

Cookie 中存储中文的问题

中文编码:需使用 URLEncoder 编码,URLDecoder 解码

/**
*1.使用中文 要用  URLEncoder.encode() 进行编码,读取时用  URLDecoder.decode() 解码
*/
// 编码中文
String name = URLEncoder.encode("姓名", "UTF-8");
String value = URLEncoder.encode("张三", "UTF-8");

// 创建 Cookie
Cookie cookie = new Cookie(name, value);
response.addCookie(cookie);

// 解码(获取时)
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
    String decodedName = URLDecoder.decode(c.getName(), "UTF-8");
    String decodedValue = URLDecoder.decode(c.getValue(), "UTF-8");
}
同名 Cookie 的覆盖问题

若服务器发送重复的 Cookie(相同 Name + Domain + Path)会覆盖掉原来的Cookie

浏览器对 Cookie 的数量和大小限制

单个 Cookie ≤ 4KB,域名下 Cookie 总数通常 ≤ 150。

创建与发送的前提条件
  • Cookie 已存储在浏览器中
    服务器通过response.addCookie()发送,客户端接收并保存
  • Cookie 未过期
    如果设置了maxAge,浏览器在有效期内保留Cookie,否则会话结束就删除
  • 作用域匹配
    Domain和Path决定了Cookie发送的范围。
  • 作用范围
    Cookie 默认绑定到域名和路径



HttpSession对象

HttpSession 是 Java Servlet 规范中用于 管理用户会话状态 的核心接口.因为session本身属于HTTP协议的范畴

它允许服务器在多个 HTTP 请求之间跟踪单个用户的状态,存储用户专属的临时数据

核心作用:

  • 标识用户:通过唯一的 Session ID 关联多次请求。
  • 共享数据:在同一会话中跨请求存储用户数据(如用户信息、临时配置)。

对于服务器而言,每一个连接到他的客户端都是一个session, servlet容器使用这个接口创建 http客户端和
http服务端之间的会话


标识符 JSESSIONID

Sesson是为了标识一次会话,那么该会话应有一个唯一的标志,这个标志就是sessionID, 客户端通过 Session ID 告诉服务器“我是谁”

存储方式
默认:通过 Cookie 存储(如 JSESSIONID=ABC123)
备用:若 Cookie 被禁用,通过 URL 重写

JSESSIONID 的工作原理
Session ID 的传递方式
  1. 首次请求
  • 服务器检查:用户首次访问服务器时,请求头中 不携带 JSESSIONID

  • 创建 Session未找到(如 Session 已过期/自己删除了),创建新 Session 并生成新 JSESSIONID。 ( 若找到对应 Session,复用现有数据 )

  • 返回 Cookie:服务器通过响应头 Set-Cookie 发送给客户端。

HTTP/1.1 200 OK  
Set-Cookie: JSESSIONID=ABC123; Path=/; HttpOnly
  • 客户端存储:浏览器保存此 Cookie,后续请求自动携带。
  1. 后续请求(携带 JSESSIONID)

默认方式:

  • 客户端请求:浏览器自动在请求头中附加通过JSESSIONID( Cookie 自动携带 )
GET /app/home HTTP/1.1  
Cookie: JSESSIONID=ABC123  
  • 服务器识别:服务器通过 JSESSIONID 找到对应的 HttpSession,恢复用户会话数据

禁用 Cookie 时:若后续请求未携带,则认为客户端禁用了 Cookie。
自动切换至 URL 重写模式( 将 JSESSIONID 直接附加到 URL 的路径后),所有动态生成的链接需调用 response.encodeURL()

http://example.com/app/home;jsessionid=ABC123

### 客户端和服务器的“感知”本质

客户端的“感知”:

  • 无法读取 Session 数据:

客户端只能看到 Session ID,无法直接访问服务器存储的会话数据(如用户邮箱、购物车内容)。

示例:就像你持有银行卡号,但无法直接查看账户余额或交易记录。

  • 无法修改 Session 数据:

Session 数据完全由服务器管理,客户端无法篡改。即使恶意修改 Session ID,服务器也会因找不到对应数据而视为无效。

服务器的“感知”: 完全掌控 Session 数据

单机部署时,Session 通常存储在服务器内存

服务器通过 Session ID 找到对应的 Session 对象,并管理其数据(如用户信息、会话时间等)。

服务器完全掌控 Session 内容,包括创建、修改和销毁。

HttpSession 的常用方法
package com.xxx.demo5;  
  
import java.io.*;  
  
import jakarta.servlet.ServletException;  
import jakarta.servlet.http.*;  
import jakarta.servlet.annotation.*;  
  
/**  
 * sesson对象的获取  
 *  request.getSesson()  
 *  当获取session对象是,会先判断session对象是否存在,如果存在,则获取session()对象,  
 *  常用方法  
 *     获取session的会话标识符      getId()  
 *     获取session的会话标识符      getCreationTime()  
 *     获取最后一次访问的时间        getLastAccessedTime()  
 *     判断是否是新的session对象    isNew()  
 */@WebServlet("/ser01")  
public class Servlet01 extends HttpServlet{  
    @Override  
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
     //创建session对象  
      HttpSession session = req.getSession();  
     //获取session的会话标识符  
      String id=session.getId();  
      System.out.println("id:"+id);  
      //获取session的会话标识符  
      System.out.println(session.getCreationTime());  
      //获取最后一次访问的时间  
      System.out.println(session.getLastAccessedTime());  
      //判断是否是新的session对象  
      System.out.println(session.isNew());  
  
    }  
}

第一次访问,true 第二次false
![[Pasted image 20250305232138.png]]

session域对象

创建与获取

// 获取当前 Session,若不存在则创建新 Session
HttpSession session = request.getSession();
// 获取 Session 但不自动创建(若不存在返回 null)
HttpSession session = request.getSession(false);

数据存取

存储数据:
session.setAttribute("user", "admin"); // 键值对存储对象
读取数据:
String user = (String) session.getAttribute("user"); // 需强制类型转换
删除数据:
session.removeAttribute("user"); // 移除单个数据

Session 作用域与请求转发/重定向

场景Request 作用域Session 作用域
请求转发✅ 有效✅ 有效
重定向❌ 无效✅ 有效

why 只要还是一个会话就不会失效

注意

Session的创建与存储:服务器生成Session ID,并通过Cookie发送给客户端。客户端存储这个ID,之后的请求都会带上它,服务器根据ID找到对应的session数据。

客户端和服务器感知的区别 : 客户端只知道Session ID,而服务器存储了实际的数据。

新浏览器无法获取旧session的原因 : Session ID存储在旧浏览器的Cookie中,新浏览器没有这个ID

session对象的销毁

1. 默认超时配置(Tomcat环境)

默认存活时间 : Tomcat中Session默认存活时间为 30分钟。基于不活动时间. 一旦操作 ,计时会重置。
修改默认时间 :
可修改Tomcat的conf/web.xml文件

<session-config>
    <session-timeout>15</session-timeout> <!-- 修改为15分钟 -->
</session-config>

2. 自定义超时配置

设置超时:
setMaxInactiveInterval()

HttpSession session = request.getSession();
session.setMaxInactiveInterval(15); // 单位:秒(此处设为15秒)
查看当前超时时间:
int timeout = session.getMaxInactiveInterval(); // 返回单位为秒
3.立即销毁

通过 session,invalidata() 方法让 session 立即失效

 session,invalidata()
4.关闭浏览器失效

session底层依赖cookie ,cookie对象默认只在浏览器中存活,关闭浏览器即失效

注意:

服务器端Session对象不会立即销毁,需等待超时(默认30分钟)。
客户端因丢失JSESSIONID,无法关联原Session,表现为新会话

5.关闭服务器

所有的东西都失效

  • 默认行为:
    关闭服务器(Tomcat/JVM终止)时,内存中所有Session对象立即销毁,未持久化的Session数据永久丢失。

  • 持久化场景:
    若配置了Session持久化(如保存到文件/数据库),服务器正常关闭时会将Session序列化到存储介质,重启后自动恢复。

    但需注意:

非默认配置:Tomcat默认不启用持久化,需手动配置Manager组件(如PersistentManager)。
异常关闭:服务器崩溃或强制终止时,Session数据仍会丢失。

概念 :
会话(Session):
用户与服务器的一次持续交互过程(如从登录到退出或超时)。
HttpSession 对象:
每个会话对应一个唯一的 HttpSession 对象,存储用户专属数据。
会话 ID:
通过 Cookie(默认 JSESSIONID)或 URL 重写标识用户会话

ServeletContext

每一个web应用有且仅有一个ServletContext对象,又称为Application对象 , 提供了一种在应用程序范围内共享数据的方式

从名称中可知,该对象是与应用程序相关的

在web容器启动时,会为每一个web应用程序创建一个对应的ServletContext对象

特点:在整个项目中就只有一个ServletContext对象

创建:tomcat一启动就会为部署在它上面的项目创建一个对应的全局管理者-ServletContext
销毁:tomcat一关闭就会销毁全局管理者-ServletContext

唯一性: 无论应用中有多少 Servlet、过滤器或监听器,它们共享同一个 ServletContext

核心作用: 它是整个 Web 应用的“全局管理中心”

共享数据: 作为域对象用来共享数据,此时的数据在整个应用程序中共享(如在线用户列表、缓存)。
访问配置:读取 web.xml 中的全局参数(如数据库连接信息)。
操作资源:获取应用内的文件路径、读取配置文件等。
生命周期管理:在应用启动/关闭时初始化或释放资源(如数据库连接池)。

在实现类中获取
//通过request获取
ServletContext servletContext = req.getServletContext();
//通过session获取
ServletContext servletContext1 = req.getSession().getServletContext();
//通过ServletConfig对象获取
 ServletContext servletContext2 = getServletConfig().getServletContext();
//直接获取
ServletContext servletContext3 = getServletContext();

所有方式等价 : 无论哪种方式,最终获取的都是同一个 ServletContext 实例(应用全局唯一)。

适用场景

优先使用方式(直接获取):代码最简洁。

在非 Servlet 类中(如监听器、过滤器):

  1. 监听器:通过 ServletContextEvent.getServletContext()。
  2. 过滤器:通过 FilterConfig.getServletContext()

避免滥用方式
(通过 HttpSession):除非已存在会话且需要同时操作会话数据


常用方法
 //1.直接获取当前的版本信息
String serverInfo=req.getServletContext().getServerInfo();
System.out.println("当前的版本信息"+serverInfo);
//获得项目的真实路径
String realPath=req.getServletContext().getRealPath("/");
System.out.println("获取项目的真实路径"+realPath);

Cookie、Session 与 ServletContext 的关系与区别

用途

Cookie                   用户身份标识、偏好设置		
HttpSession              登录状态、购物车数据
ServletContext           全局计数器、数据库连接池配置

Cookie:用户身份标识与偏好设置
用途:
用户身份标识:通过存储 JSESSIONID 或自定义 Token(如 JWT)实现会话跟踪。
偏好设置:存储用户选择的语言、主题、时区等非敏感配置。
原因:
客户端存储:Cookie 数据由浏览器管理,可跨请求自动携带,适合轻量级、频繁访问的标识信息。
生命周期可控:通过 setMaxAge() 设置有效期,如长期记住用户偏好
跨路径/域名限制:通过 setPath() 和 setDomain() 控制作用范围,避免数据污染。

Session:登录状态与购物车数据
用途:
登录状态:用户认证后存储用户 ID、角色等敏感信息,维持会话。
购物车数据:临时保存用户选择的商品列表及数量,支持增删改查操作
原因:
服务器端安全性:Session 数据存储在内存或 Redis,避免客户端篡改(如购物车商品价格)
会话级隔离:每个用户拥有独立 Session,避免数据混淆(如不同用户的购物车)
自动过期机制:默认 30 分钟无活动销毁,防止长期占用资源

ServletContext:全局计数器与数据库连接池配置
用途:
全局计数器:统计在线用户数、网站访问量等全应用共享数据。
数据库连接池配置:存储连接池对象(如 HikariCP 实例),供所有 Servlet 复用。
原因:
应用级共享:ServletContext 生命周期与应用一致,适合长期存续的全局资源。
线程安全控制:需通过 synchronized 或原子类(如 AtomicInteger)管理全局计数器,避免并发问题。
配置集中管理:通过 web.xml 或注解加载数据库连接参数,统一维护

用户登录流程

步骤:
1.用户提交登录表单,服务器验证后创建 Session,存储用户信息。
2.通过 Set-Cookie 下发 JSESSIONID 至浏览器。
3.后续请求自动携带 Cookie,服务器通过 ID 恢复会话数据。

ServletContext 的角色 :记录全局登录用户数或在线状态。



Session和Cookie的区别

Session:保存在服务器,Session是一个对象保存在Java虚拟机中
保存的数据是Object
随着会话的结束而销毁
保存重要信息

Cookie:保存在浏览器
只能保存String类型,类似于文本文件,存放的都是数据,而不是对象
可以长期保存在浏览器,与会话无关
保存不重要信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值