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

SpringSession源码分析

默认对常规Session的理解和使用,如何使用Set-Cookie。

Maven库

常见的spring-session-data-redis依赖spring-session-core

    <dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-core</artifactId></dependency>

带着问题看源码

1、Controller代码块内request.getSession()是在哪创建的呢?
2、响应头Set-Cookie是在什么地方赋值的呢?

SessionRepositoryFilter 拦截器

org.springframework.session.web.http.SessionRepositoryFilter

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);// 请求包装,进入包装类可以看到request.getSession()源码SessionRepositoryFilter<S>.SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response);SessionRepositoryFilter<S>.SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(wrappedRequest, response);try {filterChain.doFilter(wrappedRequest, wrappedResponse);} finally {// 响应头`Set-Cookie`赋值入口(这里不理解为啥使用请求提交,而不是用响应提交`wrappedResponse.commitSession()`)// 方法跳转到DefaultCookieSerializer类就看见具体Set-Cookie了wrappedRequest.commitSession();}}

SessionRepositoryRequestWrapper 包装类

org.springframework.session.web.http.SessionRepositoryFilter.SessionRepositoryRequestWrapper
Spring中存在很多继承HttpServletRequestWrapper的包装类

        public SessionRepositoryFilter<S>..SessionRepositoryRequestWrapper.HttpSessionWrapper getSession(boolean create) {SessionRepositoryFilter<S>..SessionRepositoryRequestWrapper.HttpSessionWrapper currentSession = this.getCurrentSession();if (currentSession != null) {return currentSession;} else {S requestedSession = this.getRequestedSession();if (requestedSession != null) {if (this.getAttribute(SessionRepositoryFilter.INVALID_SESSION_ID_ATTR) == null) {requestedSession.setLastAccessedTime(Instant.now());this.requestedSessionIdValid = true;currentSession = new HttpSessionWrapper(requestedSession, this.getServletContext());currentSession.markNotNew();this.setCurrentSession(currentSession);return currentSession;}} else {if (SessionRepositoryFilter.SESSION_LOGGER.isDebugEnabled()) {SessionRepositoryFilter.SESSION_LOGGER.debug("No session found by id: Caching result for getSession(false) for this HttpServletRequest.");}this.setAttribute(SessionRepositoryFilter.INVALID_SESSION_ID_ATTR, "true");}if (!create) {return null;} else if (SessionRepositoryFilter.this.httpSessionIdResolver instanceof CookieHttpSessionIdResolver && this.response.isCommitted()) {throw new IllegalStateException("Cannot create a session after the response has been committed");} else {if (SessionRepositoryFilter.SESSION_LOGGER.isDebugEnabled()) {SessionRepositoryFilter.SESSION_LOGGER.debug("A new session was created. To help you troubleshoot where the session was created we provided a StackTrace (this is not an error). You can prevent this from appearing by disabling DEBUG logging for " + SessionRepositoryFilter.SESSION_LOGGER_NAME, new RuntimeException("For debugging purposes only (not an error)"));}S session = SessionRepositoryFilter.this.sessionRepository.createSession();session.setLastAccessedTime(Instant.now());currentSession = new HttpSessionWrapper(session, this.getServletContext());this.setCurrentSession(currentSession);return currentSession;}}}// 看这里@Overridepublic SessionRepositoryFilter<S>..SessionRepositoryRequestWrapper.HttpSessionWrapper getSession() {return this.getSession(true);}

DefaultCookieSerializer

org.springframework.session.web.http.DefaultCookieSerializer
特别注意地方是:Set-Cookie内值是通过Base64加密的。

    public void writeCookieValue(CookieSerializer.CookieValue cookieValue) {HttpServletRequest request = cookieValue.getRequest();HttpServletResponse response = cookieValue.getResponse();StringBuilder sb = new StringBuilder();sb.append(this.cookieName).append('=');String value = this.getValue(cookieValue);if (value != null && value.length() > 0) {this.validateValue(value);sb.append(value);}int maxAge = this.getMaxAge(cookieValue);if (maxAge > -1) {sb.append("; Max-Age=").append(cookieValue.getCookieMaxAge());ZonedDateTime expires = maxAge != 0 ? ZonedDateTime.now(this.clock).plusSeconds((long)maxAge) : Instant.EPOCH.atZone(ZoneOffset.UTC);sb.append("; Expires=").append(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME));}String domain = this.getDomainName(request);if (domain != null && domain.length() > 0) {this.validateDomain(domain);sb.append("; Domain=").append(domain);}String path = this.getCookiePath(request);if (path != null && path.length() > 0) {this.validatePath(path);sb.append("; Path=").append(path);}if (this.isSecureCookie(request)) {sb.append("; Secure");}if (this.useHttpOnlyCookie) {sb.append("; HttpOnly");}if (this.sameSite != null) {sb.append("; SameSite=").append(this.sameSite);}response.addHeader("Set-Cookie", sb.toString());}

🔚

源码分析主要是找到入口,关键入口代码已经贴上了,剩下的自己打断点看吧。

相关文章:

SpringSession源码分析

默认对常规Session的理解和使用&#xff0c;如何使用Set-Cookie。 Maven库 常见的spring-session-data-redis依赖spring-session-core <dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-core</artifactId&…...

IIC

IIC 目录 IIC BH1750型号的光照传感器 IIC通信协议 iic物理层 IIC软件层协议 -- 那么一主多从&#xff0c;怎么选中与指定的从机通信呢&#xff1f; 从机设备地址 -- 从手册中查看 IIC 写操作 IIC 读操作 硬件IIC和模拟 IIC 使用 模拟 IIC 使用 &#xff01;&…...

LLM Observability: Azure OpenAI (一)

作者&#xff1a;来自 Elastic Vinay Chandrasekhar•Andres Rodriguez 我们很高兴地宣布 Azure OpenAI 集成现已全面上市&#xff0c;它提供了对 Azure OpenAI 服务性能和使用的全面可观察性&#xff01;另请参阅本博客的第 2 部分 虽然我们已经提供了对 LLM 环境的可视性一段…...

qt QBrush详解

1、概述 QBrush是Qt框架中的一个基本图形对象类&#xff0c;它主要用于定义图形的填充模式。QBrush可以用于填充如矩形、椭圆形、多边形等形状&#xff0c;也可以用于绘制背景等。通过QBrush&#xff0c;可以设置填充的颜色、样式&#xff08;如实心、渐变、纹理等&#xff09…...

Excel函数CUnique连接合并指定区域的唯一值

上一篇文章向大家介绍了如何使用VBA在低版本Excel中创建unique函数的方法&#xff0c;今天我跟大家分享一下如何使用函数连接指定区域的唯一值&#xff0c;也就是将unique函数获取的唯一值连接合并成一个&#xff0c;并指定连接符。 同样&#xff0c;我们需要先创建一个自定义的…...

机械革命屏幕设置为RGB

机械革命屏幕设置为RGB 如何设为机械革命屏幕显示为RGB如何设置1.win菜单下输入“显卡控制中心”2.选择显示器3.设置为RGB4.饱和度大家设为自己舒服的就行5.调整亮度 参考来源 如何设为机械革命屏幕显示为RGB 之前买的显示器&#xff0c;感觉调成sRGB看起来非常舒服。就想着是…...

开源项目-投票管理系统

哈喽,大家好,今天主要给大家带来一个开源项目-投票管理系统 投票管理系统主要有首页,发起投票,管理投票,参与投票,查看投票等功能 首页 为用户提供了一键导航到各个功能模块的便捷途径。 新增投票 用户可以在此轻松创建新的投票活动,设置投票主题、选项等信息。 管理…...

LeetCode 104.二叉树的最大深度

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1…...

Android启动流程_Init阶段

前言 本文将会介绍 Android 启动流程&#xff0c;将基于 Android 10 代码逻辑介绍原生启动过程。 bootloader 上电 -> 加载 recovery 镜像或者 boot 镜像 -> linux kernel 启动 -> 加载 init 进程 -> 加载 zygote 进程 -> systemserver 进程 -> 系统启动 …...

萤火虫算法优化BILSTM神经网络多输入回归分析

目录 LSTM的基本定义 LSTM实现的步骤 BILSTM神经网络 代码 结果分析 展望 完整代码下载:的MATALB代码(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88755564 背影 bp神经网络是一种成熟的神经网络,应用非常广,本文用萤火虫算法…...

在线QP(QuotedPrintable)编码解码工具

具体前往&#xff1a;Quoted-printable在线编码解码工具-将给定文本编码为:可打印字符引用编码(简称&#xff1a;QP编码)&#xff0c;也支持在线解码...

【已解决】cra 配置路径别名 @ 后,出现 ts 报错:找不到模块“@/App”或其相应的类型声明。ts(2307)

cra 配置路径别名 后&#xff0c;出现 ts 报错&#xff1a;找不到模块“/App”或其相应的类型声明。ts(2307) 然后可以在 tsconfig.json 中配置 baseUrl 和 paths &#xff1a; {"compilerOptions": {"target": "es5","lib": [&quo…...

leetcode-643. 子数组最大平均数 I

文章目录 二 解法2.1 每次都重新计算2.2 使用窗口 给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。请你找出平均数最大且 长度为 k 的连续子数组&#xff0c;并输出该最大平均数。任何误差小于 10-5 的答案都将被视为正确答案。二 解法 2.1 每次都重新计算 超时 pu…...

论分布式架构设计及其实现

一、引言 随着互联网用户规模的扩大和需求的多样化&#xff0c;传统的集中式架构已经难以支撑高并发、高可用的系统要求。分布式架构的出现&#xff0c;提供了将计算和存储分布到不同服务器上的解决方案&#xff0c;有效提高了系统的可扩展性和容灾能力。分布式架构目前已广泛…...

基于BP神经网络的手写体数字图像识别

基于BP神经网络的手写体数字图像识别 摘要 在信息化飞速发展的时代&#xff0c;光学字符识别是一个重要的信息录入与信息转化的手段&#xff0c;其中手写体数字的识别有着广泛地应用&#xff0c;如&#xff1a;邮政编码、统计报表、银行票据等等&#xff0c;因其广泛地应用范围…...

QT——串口调试助手

目录 1.QSerialPort类包含了很多有关串口的API 2.实现串口的打开 2.1 方法一&#xff1a;通过函数实现 2.2 方法二&#xff1a;在ui界面右下角实现 3. 实现定时发送 3.1类的私有成员中添加定时器QTimer timer并去构造函数中初始化它 3.2帮助文档中有QTimer类相关的说明 …...

国产操作系统卖疯了!最营收7.84亿,最低1.5亿

最近看各种报道&#xff0c;似乎国产化有提速的绩效&#xff0c;那么既然如此&#xff0c;各个国产操作系统厂商是不是都起飞了呢&#xff1f; 周末闲暇之余&#xff0c;我们来看看各家的营收表现。 银河麒麟2024年1-9月一共卖了多少钱&#xff1f; 前几天中国软件发布了202…...

2024年华为OD机试真题-最小的调整次数-Python-OD统一考试(E卷)

最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。 题目描述: 有一个特异性的…...

React.js教程:从JSX到Redux的全面解析

文章目录 介绍react脚手架jsx语法和react组件jsx的基本语法jsx的行内样式jsx的类名classNameif条件渲染map循环渲染创建组件方法 可视区渲染 (React- virtualized)React-redux 介绍 javascript库&#xff0c;起源于Facebook的内部项目&#xff0c;类似于vue特点 声明式组件化 …...

二叉苹果树

AcWing 1074. 二叉苹果树【有依赖背包DP】 - AcWing 问题描述 在一棵有权无向树中&#xff0c;从某个节点&#xff08;这里假设为节点 1&#xff09;出发&#xff0c;遍历树的子节点&#xff0c;每经过一条边会获得对应的权重值。在访问节点数的限制下&#xff08;即体积限制…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...