文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用Spring Session管理分布式会话时遇到的反序列化问题怎么解决

2024-04-02 19:55

关注

这篇文章主要介绍“使用Spring Session管理分布式会话时遇到的反序列化问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“使用Spring Session管理分布式会话时遇到的反序列化问题怎么解决”文章能帮助大家解决问题。

  问题浮现

  我们在使用SpringSession时(其实在问题出现时,我们并没有意识到和这儿有关联),遇到了一个隐藏较深的问题。我们像往常一样,在用户登录成功之后,将用户的实体类信息实例化保存到了session中,且session最后保存到了redis里面,这个过程其实是没有什么问题的。

  随着时间的推移业务的迭代变化,用户实体需要为更新的需求增加额外的字段,于是我们顺其自然的在类中追加其他String类型的属性,结果上了测试环境,发现我们无法进入到登录页面,从浏览器控制台上我们发现这个请求因为无法获取正确的鉴权而不断报302,并且浏览器错误主页提示我们“清除浏览器cookie”,当我们照做之后,登录页面神奇般的可以打开并且我们能够顺利登录系统和使用系统了。在我们回到服务端查看后台日志时,我们看到时在redis中出现了反序列化的问题,而且日志报的很蹊跷,并不是我们的业务代码的某一行直接抛出的日志,这给我们定位问题带了一点麻烦。

  分析问题

  首先反序列化出现问题,我们首先能够想到的就是给用户实体加了额外属性导致的,但是为何会出现反序列化问题呢?原因看起来很简单,我们的用户实体类确实实现了Serializable接口,但是我们并没有显示的写出序列化的serialVersionUID,这在实体变更了属性字段之后反序列化回来,就一定会反序列化失败的,因为在你没有指定序列号serialVersionUID号的时候,系统默认都是以类名称类属性等来自动生成的,不同的属性名称得出的序列化值肯定是不一样的,解决的方法很简单,就是在初始化类的时候,主动写名序列化serialVersionUID号。

  但是我们的程序现在已经在生产环境了,无法做到这一步,因为按照新的类来生成序列号,显然是前后不一致的,给新加的字段加上transient字段?这种做法也步行,这意味着这个字段的值将无法序列化,后面其他系统肯定是使用不了的,这些额外增加的字段就没有存在意义了。

  在对报错日志进行抽丝剥茧逐行分析之后,发现这个异常居然和SpringSession有关系。

  因为我们在用户成功登录系统之后,使用了request.getSession()。setAttribute("xx", "xx")操作,我们将我们的用户实体放到了session中,并由SpringSession成功的放到了Redis里面,并且我们的会话时长是48小时;在我们新的实体更新进来之后,系统一发布,打开登录页面系统对SpringSession中的内容进行初始化,就发现了用户实体无法从Redis中初始化回来,因为前后的序列化号对不上了,于是就疯狂的报反序列化失败,这是根本问题所在。

  解决问题

  那怎么解决呢?很明显,聪明的浏览器给了我们第一个解决方案,那就是清除浏览器Session。

  因为上面我们说到,SpringSession会在浏览器里面自动设置一个名为SESSION的cookie值,这个值是为了后台服务能够在Redis中找到之前存放的Session以便能够识别是统一用户,当浏览器清除了Cookie之后,这个SESSION的值就失去了,于是系统重新为这个浏览器发起请求的用户重新生成SESSION值,这个请求也就无法在redis中找到对应的Session会话,也就没有将用户实体反序列化这个过程,登录程序当然能够正常进行,而且往后的交互都是正常的了。

  那么还有另外的解决方法,从Redis端,既然SpringSession会用这个SESSION去Redis中找对应的值,那么我们就将这个Redis中存放的Session内容进行清除,找不到内容自然就无需反序列化了,不过此时正常访问的用户,也会因为请求没有找到统一的Session而认为是会话过期强制退出。这里在redis中清除内容的方式,可以使用下面的命令:

  $ redis-cli keys '*' | xargs redis-cli del

  $ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e

  第三种方式呢,就是从代码端改造,反序列化失败的本质就是原来的类新增了属性,而且类没有显示的指定序列化serialVersionUID,那么我们变通一下,保持原来的类不变呗,新增的属性放到一个继承了这个用户实体类的类当中,后面我们就用这个新的类,保持老的类不变(属性类型和数量等的都不变),那就行了。是的,就是使用新类的方式,新类继承用户实体类,保持用户实体类不变,新类当中增加需要补充的属性字段,同时需要序列化,这样SpringSession在初始化时,它依然能够反序列找到原来没有变通的那个类,我们自己也能够很好的实现我们新的需求了。

关于“使用Spring Session管理分布式会话时遇到的反序列化问题怎么解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯