Shiro Session集群共享存入Redis中SimpleSession的transient 属性不能序列化
最开始实现共享Session的方法,是基于这篇博客实现的SpringBoot+redis 实现shiro集群共享session 。但是原有项目有redis的一些配置,就没用文章里的redis序列化方式,踩了一个大坑。
一、问题描述
通过 redis 缓存 shiro 的 session,取值的时候 session id内容为 null。
1 | java.lang.IllegalArgumentException: The org.apache.shiro.session.mgt.DelegatingSession implementation requires that the SessionKey argument returns a non-null sessionId to support the Session.getId() invocations. |
断点调试发现redis在存入SimpleSession时都是有值的,只是获取出来后一些属性是为null的。 What? 小朋友你是不是有很多的问号????
二、原因分析
因为 shiro 的 Session 是一个 SimpleSession 类,其中属性用 transient 修饰,即不能被序列化。
RedisTemplate 默认使用JdkSerializationRedisSerializer,这个序列化模式会将value序列化成字节码,这样缓存shiro的session就没有什么问题。 但是一般都会用Fastjson、Jackson2Json来指定redis的序列化方式,这样的方式就会导致数据存取不一致问题。
1 | public class SimpleSession implements ValidatingSession, Serializable { |
三、解决方案
- 方案1. 修改序列化工具类
- 方案2.继承SimpleSession并重写,让相关的字段可以被序列化(不被transient修饰)
我最终结果是放弃了自己写RedisManager、SessionDAO,因为项目框架这边redis序列化相关的不好改,使用crazycake写的开源插件。
详见 : 2020-04-01-SpringBoot+Shiro基于Redis实现共享Session
参考文章: