SpringSesion共享使用、自定义Session作用域

1|0SpringSesion共享使用、自定义Session作用域

通常情况下,Tomcat、Jetty等Servlet容器,会默认将Session保存在内存中。如果是单个服务器实例的应用,将Session保存在服务器内存中是一个非常好的方案。但是这种方案有一个缺点,就是不利于扩展。

目前越来越多的应用采用分布式部署,用于实现高可用性和负载均衡等。那么问题来了,如果将同一个应用部署在多个服务器上通过负载均衡对外提供访问,如何实现Session共享?

实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat、Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中。

下面我们将在springcloud微服务项目中,使用第三方存储服务保存(redis),但是如果是直接使用redis,要求对我们的代码进行修改。所以使用spring session。spring session的原理是对我们的request和response进行了包装。因为session的获取是request.getSession() ,所以包装了请求体,而cookie的设置需要设置到response中所以也包装了响应体。spring session很完美的解决了代码重构的问题。还能对接不同的存储中间件,不仅仅限于redis。子域共享问题。自定义cookie的响应信息。设置cookie 的作用域domean 只能是当前域名或者父域名。domean 是子域名可以拿到父域名的信息,domean是父域名不能拿到子域名的信息。

2|0代码

spring session guide

Sample Applications that use Spring Boot session redis guide

Sample Applications that use Spring Java-based configuration session redis guide

[HttpSession with Redis JSON serialization](https://github.com/spring-projects/spring-session/tree/2.1.12.RELEASE/samples/boot/redis-json)

依赖

<!-- 整合spring session完成session 共享问题 --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>

配置文件

# redis的连接信息 spring.redis.host=192.168.1.10 spring.redis.port=6379 # 将session数据保存到redis中 spring.session.store-type=redis spring.session.redis.flush-mode=on_save spring.session.redis.namespace=spring:session

启用自动配置(启动类配置 )

@EnableRedisHttpSession // 整合redis作为session存储,就是通过filter包装了我们的请求体和响应体 @EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class GulimallAuthServerApplication { public static void main(String[] args) { SpringApplication.run(GulimallAuthServerApplication.class, args); } }

Spring sessioin 中redis的序列化、cookie的自定义设置

/** * * Description:设置Session作用域、自定义cookie序列化机制 * date:2020/11/5 */ @Configuration public class GlMallSessionConfig { @Bean public CookieSerializer cookieSerializer(){ DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); // 明确的指定Cookie的作用域 cookieSerializer.setDomainName("gulimall.com"); cookieSerializer.setCookieName("FIRESESSION"); return cookieSerializer; } /** * 自定义序列化机制 * 这里方法名必须是:springSessionDefaultRedisSerializer */ @Bean public RedisSerializer<Object> springSessionDefaultRedisSerializer(){ return new GenericJackson2JsonRedisSerializer(); } }
---存入session(统一存储到redis,进行服务之间进行共享Session) @PostMapping("/login") public String login(UserLoginVo userLoginVo, RedirectAttributes redirectAttributes, HttpSession session){ //远程登录 R login = memberFeignService.login(userLoginVo); if (login.getCode()==0){ //登录成功 MeberRespVo meberRespVo = login.getData("data", new TypeReference<MeberRespVo>() { }); //存入session(统一存储到redis,进行服务之间进行共享Session) session.setAttribute("loginUser",meberRespVo); return "redirect:http://gulimall.com"; }else { HashMap<String, String> errors = new HashMap<>(); errors.put("errors",login.getData("msg",new TypeReference<String>(){})); redirectAttributes.addFlashAttribute("errors",errors); return "redirect:http://auth.gulimall.com/login.html"; } }

在获取session的时候不同服务只需要在获取 redis中session的key即可(session.loginUser.nickname)loginUser为key。

注意:需要使用共享Session的服务都要进行 以上的配置,不然使用不了存在 redis中的Session。

Spring Session原理

Session核心原理:
1)、@EnableRedisHttpSession导入RedisHttpSessionConfiguration配置
1、给容器添加了一个组件RedisIndexedSessionRepository
RedisIndexedSessionRepository:redis操作session。session的增删改查封装类
2、SessionRepositoryFilter --》Filter: session存储的过滤器,每个请求都必须经过filter
1、创建的时候 ,就自动从容器中获取SessionRepository
2、原始的request,response都被包装。SessionRequestWrapper,SeesionRepositoryResponseWrapper
3、以后获取session。request.getSession();
//SessionRepositoryRequestWrapper
4、wrappedRequest.getSession()==>SessionRepositry中获取的。
装饰者模式:把原生的请求封装成自己的
Seesion会自动延期,redis中也是有过期时间的

#### 暑假到现在很久没更新了 因为在学校没时间(好吧其实就是因为自己懒哈哈,在学校安逸过头了)、今天刚弄完谷粒商城分布式Session共享的问题,想要更加详细的知识关注:https://gitee.com/jinronga/guilimall,不要停止我们的脚步。继续努力!

__EOF__

本文作者金融融融融果果
本文链接https://www.cnblogs.com/jinronga/p/13940925.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   金融融融融果果  阅读(1303)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示