博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
session丢失原因 java_session没有过期,其保存的数据无故丢失的原因
阅读量:4678 次
发布时间:2019-06-09

本文共 4731 字,大约阅读时间需要 15 分钟。

问题:

我们经常会做到的一个功能,将登录用户信息保存到session中,在页面上显示登录用户名。但是,如果很短时间内甚至几秒没有刷新这个页面的话,这个用户名就消失了,其实就是session中保存的用户数据丢失了。

百度过很多,大部分说是session过期时间设置长一点,或者tomcat的配置问题等等,但都没能解决....在上一篇博客里问到这个问题的时候,有个博友的评论给了我思路,果然O(∩_∩)O哈哈~ 先感谢!!!

然后 看测试过程吧 ↓↓↓

下面这个是用户实体类:

1 packagecom.lizhou.entity;2

3 /**

4 * 用户类5 *@authorbojiangzhou6 * @date 2016年2月28日7 */

8 public classUser {9

10 private intid;11

12 privateString name;13

14 publicUser() {15

16 }17

18 public User(intid, String name) {19 this.id =id;20 this.name =name;21 }22

23 public intgetId() {24 returnid;25 }26

27 public void setId(intid) {28 this.id =id;29 }30

31 publicString getName() {32 returnname;33 }34

35 public voidsetName(String name) {36 this.name =name;37 }38

39 }

用户servlet:地址栏输入http://localhost:8080/session/UserServlet进行访问,然后会重定向到showUser.jsp (这样刷新页面的时候就不会访问这个servlet了)

1 packagecom.lizhou.servlet;2

3 importjava.io.IOException;4 importjavax.servlet.ServletException;5 importjavax.servlet.annotation.WebServlet;6 importjavax.servlet.http.HttpServlet;7 importjavax.servlet.http.HttpServletRequest;8 importjavax.servlet.http.HttpServletResponse;9

10 importcom.lizhou.entity.User;11

12 /**

13 * 用户servlet14 *@authorbojiangzhou15 * @date 2016年2月28日16 */

17 public class UserServlet extendsHttpServlet {18 private static final long serialVersionUID = 1L;19

20 protected void doGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {21 request.setCharacterEncoding("UTF-8");22

23 User user = newUser();24 user.setId(1);25 user.setName("Chiangchou");26

27 //将用户信息保存到session中

28 request.getSession().setAttribute("user", user);29 //保存一个字符串信息

30 request.getSession().setAttribute("message", "用户登录成功");31

32 //重定向

33 response.sendRedirect("showUser.jsp");;34

35 }36

37 protected void doPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {38

39 }40

41 }

session监听器:监听session的创建与销毁、向session中添加属性、移除属性、更改属性。

1 packagecom.lizhou.listener;2

3 importjavax.servlet.http.HttpSessionAttributeListener;4 importjavax.servlet.http.HttpSessionBindingEvent;5 importjavax.servlet.http.HttpSessionEvent;6 importjavax.servlet.http.HttpSessionListener;7

8 /**

9 * session监听器10 *@authorbojiangzhou11 * @date 2016年2月28日12 */

13 public class SessionListener implementsHttpSessionListener, HttpSessionAttributeListener {14

15 //属性添加时间

16 private longaddTime;17

18 @Override19 public voidsessionCreated(HttpSessionEvent event) {20 System.out.println("session 创建");21 }22

23 @Override24 public voidsessionDestroyed(HttpSessionEvent event) {25 System.out.println("session 销毁");26 }27

28 @Override29 public voidattributeAdded(HttpSessionBindingEvent event) {30 System.out.println("添加属性:"+event.getName());31 //当属性保存的时候保存当前时间

32 addTime =System.currentTimeMillis();33 }34

35 @Override36 public voidattributeRemoved(HttpSessionBindingEvent event) {37 System.out.println("移除属性:"+event.getName());38 //当属性移除的时候计算属性保存时间

39 long removeTime =System.currentTimeMillis();40 long t = (removeTime-addTime)/1000;41 System.out.println("数据保存时间:"+t+"秒");42 }43

44 @Override45 public voidattributeReplaced(HttpSessionBindingEvent event) {46 System.out.println("更改属性:"+event.getName());47 }48

49 }

showUser.jsp 显示用户名

1

2 pageEncoding="UTF-8"%>

3

4

5

6

7

显示用户

8

9

10 用户名:【 ${user.name} 】11

12 信息:【 ${message} 】13

14

准备工作做好了,下面看测试:

首先直接在地址栏输入地址访问UserServlet,在doGet()里会将用户信息保存到session中,重定向到showUser.jsp时,显示用户名和信息,如图: 可以看到,User对象的属性和字符串都能显示。

e7d27a5dad97fe98596fe76badb02eb8.png

下面是控制台输出的信息:刚访问servlet后就截图的

54559bd4a611004a3788149fb0e1b495.png

然后,过了一会,控制台如图:

66fefe62986e55af33b2c1c5674c50f8.png

可以看到,54秒后,user属性移除了,message没有移除,session并没有销毁哦!!!然后刷新页面显示:这就是我们常见到的情况了....

bfcae04df163a6e1ec5ee2324741c9ab.png

然后,百度大部分说设置session过期时间长一点:但是没有效果

1

2

3 30

4

然后还有一种方法:在根目录下放一个refresh.jsp文件,内容如下:主要是第6行代码,每隔一秒刷新一下,链接到自己

1

2 pageEncoding="UTF-8"%>

3

4

5

6

7

8

9

10

11

12

13

然后在显示数据的页面(showUser.jsp)加上一句代码:

目的是不断请求服务器,我的理解是服务端以为客户端一直在使用这个对象,就不会移除这个数据了....

这样虽然达到了目的,但有很大的弊端,而且治标不治本:一直请求服务器消耗服务器资源是肯定的了,而且浏览器的刷新图标会一直跳,看着很不爽的...

9d25cc49108dda56b58681e1007e491d.png

*****************************************************************************************************************

最后,看解决办法:只需要将User实现序列化接口Serializable即可,如下:

1 packagecom.lizhou.entity;2

3 importjava.io.Serializable;4

5 /**

6 * 用户类7 *@authorbojiangzhou8 * @date 2016年2月28日9 */

10 public class User implementsSerializable {11

12 private intid;13

14 privateString name;15

16 publicUser() {17

18 }19

20 public User(intid, String name) {21 this.id =id;22 this.name =name;23 }24

25 //getter/setter方法26

27 }

将要保存到session中的对象实现序列化接口Serializable,这样用户数据就一直保存在session里了,不管你怎么刷新,除非session销毁,数据一直都在!!!

那么原因是什么呢?下面是我百度的一段:

【Object serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原来的对象。

举个例子:网络传输的时候,可以传字符串,亦可以传对象object,例如socket。传字符串的时候接收方很容易解析出来,但是,传一个对象的时候,对方读完字节流后,不知道你传的什么对象,所以没办法给转成原来的对象并解析对象的属性,这时候就要用到序列化和反序列化。类实现序列化接口,socket发送这个对象的字节流,接收方收到流后就可以将流反序列化成对象,然后使用对象的方法和属性。】

OK!!!

转载地址:http://oxfkp.baihongyu.com/

你可能感兴趣的文章
Android上下文菜单ContextMenu
查看>>
【bzoj4543】Hotel加强版(thr)
查看>>
[stm32] 中断
查看>>
RTP Payload Format for Transport of MPEG-4 Elementary Streams over http
查看>>
两个时间相差多少 .net中的timespan应用
查看>>
递归 换零钱问题——由打靶子问题引申
查看>>
Python-函数基础
查看>>
Extensible Messaging and Presence Protocol (XMPP) 简介
查看>>
Farm Irrigation
查看>>
windows平板的开发和选型
查看>>
无平方因子的数(数论初步) By ACReaper
查看>>
C语言截取字符串
查看>>
构建之法阅读笔记06
查看>>
CentOS minimal新装配置笔记
查看>>
压缩映象原理的一个应用
查看>>
Aurora — 一个在 MSOffice 内输入 LaTeX 公式的很好用插件
查看>>
关于sql优化的一个小总结
查看>>
Java语言中的正则表达式
查看>>
Java环境变量设置
查看>>
【JBPM4】判断节点decision 方法3 handler
查看>>