session没有过期,其保存的数据无故丢失的原因

问题:

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

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

然后 看测试过程吧 ↓↓↓

下面这个是用户实体类:

 1 package com.lizhou.entity;
 2
 3 /**
 4  * 用户类
 5  * @author bojiangzhou
 6  * @date 2016年2月28日
 7  */
 8 public class User {
 9
10     private int id;
11
12     private String name;
13
14     public User() {
15
16     }
17
18     public User(int id, String name) {
19         this.id = id;
20         this.name = name;
21     }
22
23     public int getId() {
24         return id;
25     }
26
27     public void setId(int id) {
28         this.id = id;
29     }
30
31     public String getName() {
32         return name;
33     }
34
35     public void setName(String name) {
36         this.name = name;
37     }
38
39 }

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

 1 package com.lizhou.servlet;
 2
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.annotation.WebServlet;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9
10 import com.lizhou.entity.User;
11
12 /**
13  * 用户servlet
14  * @author bojiangzhou
15  * @date 2016年2月28日
16  */
17 public class UserServlet extends HttpServlet {
18     private static final long serialVersionUID = 1L;
19
20     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
21         request.setCharacterEncoding("UTF-8");
22
23         User user = new User();
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) throws ServletException, IOException {
38
39     }
40
41 }

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

 1 package com.lizhou.listener;
 2
 3 import javax.servlet.http.HttpSessionAttributeListener;
 4 import javax.servlet.http.HttpSessionBindingEvent;
 5 import javax.servlet.http.HttpSessionEvent;
 6 import javax.servlet.http.HttpSessionListener;
 7
 8 /**
 9  * session监听器
10  * @author bojiangzhou
11  * @date 2016年2月28日
12  */
13 public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {
14
15     //属性添加时间
16     private long addTime;
17
18     @Override
19     public void sessionCreated(HttpSessionEvent event) {
20         System.out.println("session 创建");
21     }
22
23     @Override
24     public void sessionDestroyed(HttpSessionEvent event) {
25         System.out.println("session 销毁");
26     }
27
28     @Override
29     public void attributeAdded(HttpSessionBindingEvent event) {
30         System.out.println("添加属性:"+event.getName());
31         //当属性保存的时候保存当前时间
32         addTime = System.currentTimeMillis();
33     }
34
35     @Override
36     public void attributeRemoved(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     @Override
45     public void attributeReplaced(HttpSessionBindingEvent event) {
46         System.out.println("更改属性:"+event.getName());
47     }
48
49 }

showUser.jsp 显示用户名

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>显示用户</title>
 8 </head>
 9 <body>
10     用户名:【 ${user.name} 】
11     <br/>
12     信息:【 ${message} 】
13 </body>
14 </html>

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

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

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

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

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

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

1 <!-- 设置session失效时间(单位:分) -->
2 <session-config>
3   <session-timeout>30</session-timeout>
4 </session-config>

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

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="refresh" content="1; url=refresh.jsp">
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title></title>
 9 </head>
10 <body>
11
12 </body>
13 </html>

然后在显示数据的页面(showUser.jsp)加上一句代码:<iframe width=0 height=0 src="refresh.jsp"></iframe>

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

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

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

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

 1 package com.lizhou.entity;
 2
 3 import java.io.Serializable;
 4
 5 /**
 6  * 用户类
 7  * @author bojiangzhou
 8  * @date 2016年2月28日
 9  */
10 public class User implements Serializable {
11
12     private int id;
13
14     private String name;
15
16     public User() {
17
18     }
19
20     public User(int id, 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发送这个对象的字节流,接收方收到流后就可以将流反序列化成对象,然后使用对象的方法和属性。】

附上测试代码:session数据丢失测试代码

OK!!!

时间: 2024-10-23 08:41:49

session没有过期,其保存的数据无故丢失的原因的相关文章

session设置过期的方法(转载)

这篇文章主要介绍了php中实现精确设置session过期时间的方法,需要的朋友可以参考下 大多数据情况下我们对于session过期时间使用的是默认设置的时间,而对于一些有特殊要求的情况下我们可以设置一下session过期时间. 对此,可以在PHP中,设置php.ini,找到session.gc_maxlifetime = 1440 #(PHP5默认24分钟) 这里你可以随便设置一下过期时间.但是有人说设置以后,好象不起作用! 其实不是不起作用,而是因为系统默认: ? 1 2 session.gc

.net 内置对象之Session对象和Session的过期时间

QQ:827969653 有需要的朋友可以下载Session类:SessionHelper类 http://technet.microsoft.com/zh-cn/library/system.web.httpsessionstatebase(v=VS.90) Session过期时间设置:timeout=”10”——代表10分钟后过期(以分钟为单位). <sessionState mode="InProc" cookieless="false" timeout

Memcached保存sesion数据的方法以及安全性问题

我们都知道,传统的session数据都储存到了文件里面,这样,在一定的程度上降低了速度. 在我们在实现问题之前,应该对php.ini进行配置如下: session.save_handler = memcache //指定使用Memcached保存数据 session.save_path = "tcp://127.0.0.1:11211" //指定session数据的的连接 有时候也可以用ini_set("键","键值");来设置php.ini操作

PHP中的session永不过期的解决思路及实现方法分享

打开php.ini设置文件,修改三行如下: 1.session.use_cookies  把这个的值设置为1,利用cookie来传递sessionid  2.session.cookie_lifetime  这个代表SessionID在客户端Cookie储存的时间,默认是0,代表浏览器一关闭SessionID就作废……就是因为这个所以PHP的 session不能永久使用! 那么我们把它设置为一个我们认为很大的数字吧,999999999怎么样,可以的!就这样.  3.session.gc_maxl

保存现场数据和状态:onSaveInstanceState\onRestoreInstanceState\onCreate()

当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候. 注意上面的双引号,何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性.这种可能性有哪些?通过重写一个activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我们可以清楚地知道当某个activity

面试中被问到:Android中activity保存状态数据到底该在哪个方法中进行

今天接到一个电面,途中面试官问到一个问题,如果一个activity在后台的时候,因为内存不足可能被杀死,在这之前如果想保存其中的状态数据,比如说客户填的一些信息之类的,该在哪个方法中进行. 我听到的第一反应就是说:在onPause方法中进行保存状态的操作.但是面试官说:onPause()的持续时间很短,假如要进行一些长时间的操作呢? 然后我就纠结了,因为我知道,如果是因为内存不足而被清理,onDestroy()方法一般是不会被执行的.所以只好实话实说,只知道onDestroy在这种情况下不一定会

ThinkPHP中:检查Session是否过期

1.创建Session 1 public function index(){ 2 $sess_time=time(); 3 session('name','andy'); 4 session('time_stamp',$sess_time); 5 } 2.检查Session是否过期 1 /** 2 * 检查Session是否过期(30分钟) 3 */ 4 public function checkSessTime(){ 5 if (!$_SESSION) { 6 header('content-

ffmpeg最简单的解码保存YUV数据 &lt;转&gt;

video的raw data一般都是YUV420p的格式,简单的记录下这个格式的细节,如有不对希望大家能指出.   YUV图像通常有两种格式,一种是packet 还有一种是planar    从字面上就能理解packet的意思就是所有的yuv数据都是一股脑的放在一起,当然 内部的数据还是按照格式要求的,只是从外部来讲是一整个包包含了所有的yuv数据.最长见的YUV格式就是planar格式了.这个格式是讲yuv三个分量分别放在三个数组里.   如下图是个420p的格式图: YUV420格式是指,每

html 实体转换为字符:转换 UEditor 编辑器 ( 在 ThinkPHP 3.2.2 中 ) 保存的数据

在 ThinkPHP 3.2.2 中使用 UEditor 编辑器保存文章内容时,数据库中保存的数据都被转义成实体,例如:&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-family: 微软雅黑, &amp;#39;Microsoft YaHei&amp;#39;; color: rgb(192, 0, 0);&quot;&gt;&lt;em&gt;&lt