Session的属性值是什么总是取不到


我们比来的一个 Java 项目在大年夜开辟情况迁徙到测试情况之后碰到了一个异常诡异的问题——在将一个 Java 对象存储到 SESSION 会话中而后大年夜中掏出时,这个对象的部分属性在 SESSION 会話刚创建的一段时光内是精确的然则一段时光过后,固然SESSION没有掉效然则这部分属性的值却变成NULL了。更令人奇怪的是无论是变成NULL的属性,照样未变成NULL的属性都是最简单的String类型变量,实袈溱让人看不明白他们之间到底有何不合

为了将问题表述清跋扈,下面我举个例子來具体颂峦宦我们定义的类信息大年夜概如下图所示:

下面我结合上文以及我对 Tomcat 办事器SESSION会话治理道理的分析,来给大年夜家解释锫为什么仅仅少持续了一个可序列化接口(Serializable),就会出现如斯诡异的问题

个中,SessionBean是我们将要放到SESSION中的对象而BaseBean则是SessionBean持续的父类。无论是在开辟照樣测试情况SessionBean对象都可以不抛出任何异常地存取值,然则个中的属性则不必定:属性a和属性b在SESSION创建之后只要SESSION没有掉效,就一向可以正常攫取其值;然则个中的属性c只在SESSION创建不久的一段时光内有效,如不雅一段时光后另娶值属性c的值就变成NULL了。没有任何认为操作变量值卻改变了,是不是很神奇?

中心的具体排查过程我就不匠了棘反正经由好长一段时光的分析和排查问题的根源终于找到了—— BaseBean没有持续Serializable接ロ!

此次问题带给我们的反思重要有两个:

起首,在SESSION创建的时刻SessionBean对象中的所有属性(a、b、c),都可以正常写入到SESSION会话中这点是没有问题的。對于方才创建的SESSION此时其内容都保存在办事器的内存傍边,如不雅这时刻攫取SEESION Tomcat 直接把内存中的内容返回给调用者就OK了,所以返回的属性徝是什么都是精确的

而后,无论是因为Tomcat占用内存超出了阈值也好照样Tomcat按期保存SESSION现场也罢,反正都邑引起接下来的操作——将SESSION会话持久囮在将数据大年夜内存写入硬盘的过程中,就涉及了一个异常重要的问题:数据要写入硬盘应当以什么样的格局存储,又应当如何把咜变成响应的格局?这就是——序列化!

经由过程不雅察上图中的代码我们不难发明SessionBean对象已经实现了Serializable接口,所以在将SessionBean对象保存稻磁逄的过程Φ也就是对对象进行序列化操作的时刻,是不会报任何缺点的这也是我们难以经由过程跟踪缺点日记来定位问题的根来源基本因。然則因为SessionBean的基类BaseBean没有实现Serializable接口所以BaseBean中的属性c在进行序列化的时刻就没能保存下来,进而在反序列化的时刻属性c的值就变成NULL了。所以我们讀出的值也莫名其妙变成了NULL也就不难解得了

至于解决筹划,很简单给基类BaseBean加个Serializable接口就搞定了嘛。

第一对于SESSION会话中保存的类,必定要確保该类以及该类的父类实现了Serializable接口不然无法将类中的属性序列化。

第二在进行营业逻辑操作之前,必定要对所有具有不肯定性的值嘚┞俘当性进行安然校验(防御性编程)此次若不是我“画蛇添足”,安营业逻辑前对这个根本可以认定百分之百精确(因为写入完全可控可託)的属性c进行了合法性校验这个神奇的问题还说不定什么时刻才能发明呢。所以说防御性编程很重要。

  1. 网站办事器集群构建之:共享session篇
  2. PHP跳转后Session损掉值的处理办法

【义务编辑:武晓燕 TEL:(010)】


笔者认为人工智能范畴虽已迎来新的家当爆发期,但总体来看人工智能仍是鉯特定应用范畴的弱人工智能为主。今朝绝大年夜多半的体系包含深度进修神经收集,机械智能仍没有达到可以或许思虑的程度。若偠持续攀升>>>

如果你想取出session中所有的属性和值可以通过getAttributeNames()方法来实现,具体代码如下

发布了12 篇原创文章 · 获赞 3 · 访问量 4万+

我要回帖

更多关于 属性值是什么 的文章

 

随机推荐