替换Servlet容器的HttpSession实现集群中Session共享(With Redis)

2024-04-21 05:18

本文主要是介绍替换Servlet容器的HttpSession实现集群中Session共享(With Redis),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文是我个人在开发web-security 安全框架中使用的方案。
在Web Server集群环境中需要实现 session 共享,一个很好的方法就是将 session 数据存放至 Redis 中。我打算在自己的安全框架中集成此功能,只需要几行配置就能自动让你的 web 项目集成 redis session 共享功能。

实现思路为:

将 Servlet 容器的HttpSession实现替换成自己的实现, 如RedisHttpSession。这样当在Controlelr中调用session.setAttr()此类方法时就可以执行自己的代码。我们编写一个Filter, 在调用chain.doFilter(req, resp)时,将HttpServletRequest对象替换成我们自定义的SecurityServletRequestWrapper对象,并重写getSession()getSession(boolean)方法,让其返回我们自己的session对象,这样就完成了对session的完全控制 。

替换 Servlet 容器的 HttpSession 实现

首选需要编写SecurityServletRequestWrapper类:

public class SecurityServletRequestWrapper extends HttpServletRequestWrapper {private static Logger log = LoggerFactory.getLogger(SecurityServletRequestWrapper.class);private HttpSession session;public SecurityServletRequestWrapper(HttpServletRequest request, HttpSession session) {super(request);if (null != session) {this.session = session;}}@Overridepublic HttpSession getSession() {log.debug("getSession() invoked!");return getSession(true);}/*** 返回自定义的HttpSession实现* @param create* @return*/@Overridepublic HttpSession getSession(boolean create) {log.debug("getSession(boolean) invoked!");if (create && null == session) {log.debug("creating new Session object!");session = new NativeHttpSession(getServletContext());}return session;}
}

然后,编写一个filter, 用我们刚刚完成的SecurityHttpServetRequest替换掉doFilter()方法中的第一个参数,代码大致如下:

/*** 遍历filters, 依次执行每一个过虑器*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;// 将request对象替换成自定义的wrapper对象req = new SecurityServletRequestWrapper(req, session);chain.doFilter(req, response);}

我们必须保证在请求到来时,该过滤器第一个被调用,请求完成后,该过虑器最后被调用。这样我们便可以在chain.doFilter()之前 添加从 Redis 中读取 session的代码,在chain.doFilter()之后添加刷新 session 至 redis 的代码:

@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;// 如果开启了session cluster// 执行session cluster相关逻辑if (PageProtectionContextListener.SESSION_CLUSTER) {// 尝试从存储仓库中查询sessionHttpSession session = sessionDAO.loadSession(getSid(req));logger.debug("session loaded, result => {}", session);// 将request对象替换成自定义的wrapper对象req = new SecurityServletRequestWrapper(req, session);}chain.doFilter(req, response);// 执行session cluster相关逻辑if (PageProtectionContextListener.SESSION_CLUSTER) {// 刷新session数据// 先判断有无sessionHttpSession session = req.getSession(false);// 如果没有session, 不做任何处理if (null == session) {return;}if (false == session instanceof NativeHttpSession) {throw new UnsupportedFilterException("filter " + session.getClass() + " unsupported!");}NativeHttpSession nativeSession = (NativeHttpSession) session;if (nativeSession.isDirty()) {logger.debug("flushing session");sessionDAO.flushSession(nativeSession);}}}

以上是整体实现思路和关键代码的实现,我们可以在此基础上,根据实际需求添加自己系统需要的功能。

这篇关于替换Servlet容器的HttpSession实现集群中Session共享(With Redis)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922234

相关文章

Redis中Stream详解及应用小结

《Redis中Stream详解及应用小结》RedisStreams是Redis5.0引入的新功能,提供了一种类似于传统消息队列的机制,但具有更高的灵活性和可扩展性,本文给大家介绍Redis中Strea... 目录1. Redis Stream 概述2. Redis Stream 的基本操作2.1. XADD

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u