问题:

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

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

然后 看测试过程吧 ↓↓↓

下面这个是用户实体类:

 package com.lizhou.entity;

 /**
* 用户类
* @author bojiangzhou
* @date 2016年2月28日
*/
public class User { private int id; private String name; public User() { } public User(int id, String name) {
this.id = id;
this.name = name;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

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

 package com.lizhou.servlet;

 import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.lizhou.entity.User; /**
* 用户servlet
* @author bojiangzhou
* @date 2016年2月28日
*/
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); User user = new User();
user.setId(1);
user.setName("Chiangchou"); //将用户信息保存到session中
request.getSession().setAttribute("user", user);
//保存一个字符串信息
request.getSession().setAttribute("message", "用户登录成功"); //重定向
response.sendRedirect("showUser.jsp");; } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

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

 package com.lizhou.listener;

 import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; /**
* session监听器
* @author bojiangzhou
* @date 2016年2月28日
*/
public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener { //属性添加时间
private long addTime; @Override
public void sessionCreated(HttpSessionEvent event) {
System.out.println("session 创建");
} @Override
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("session 销毁");
} @Override
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.println("添加属性:"+event.getName());
//当属性保存的时候保存当前时间
addTime = System.currentTimeMillis();
} @Override
public void attributeRemoved(HttpSessionBindingEvent event) {
System.out.println("移除属性:"+event.getName());
//当属性移除的时候计算属性保存时间
long removeTime = System.currentTimeMillis();
long t = (removeTime-addTime)/1000;
System.out.println("数据保存时间:"+t+"秒");
} @Override
public void attributeReplaced(HttpSessionBindingEvent event) {
System.out.println("更改属性:"+event.getName());
} }

showUser.jsp 显示用户名

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 package com.lizhou.entity;

 import java.io.Serializable;

 /**
* 用户类
* @author bojiangzhou
* @date 2016年2月28日
*/
public class User implements Serializable { private int id; private String name; public User() { } public User(int id, String name) {
this.id = id;
this.name = name;
} //getter/setter方法
}

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

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

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

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

OK!!!

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

  1. Vuex 页面刷新后store保存的数据会丢失 取cookie值

    在store.js中 export default new vuex.Store({ // 首先声明一个状态 state state:{ pcid: '', postList: [], } //更新状 ...

  2. tomcat cluster session同步时保存map数据遇到的问题

    Tomcat Cluster官网:https://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html(tomcat7.0) 场景: tomcat1 ...

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

    这篇文章主要介绍了php中实现精确设置session过期时间的方法,需要的朋友可以参考下   大多数据情况下我们对于session过期时间使用的是默认设置的时间,而对于一些有特殊要求的情况下我们可以设 ...

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

    QQ:827969653 有需要的朋友可以下载Session类:SessionHelper类 http://technet.microsoft.com/zh-cn/library/system.web ...

  5. laravel中session的过期时间

    在项目开发的过程中,前后端分离 需要用session保存用户的登陆信息 这就涉及到session的有效期了 session又分为php中的session有效期和laravel中的session的有效期 ...

  6. Redis 内存优化神技,小内存保存大数据

    大家好,我是「码哥」,大家可以叫我靓仔. 这次码哥跟大家分享一些优化神技,当你面试或者工作中你遇到如下问题,那就使出今天学到的绝招,一招定乾坤! 如何用更少的内存保存更多的数据? 我们应该从 Redi ...

  7. KnockoutJS 3.X API 第七章 其他技术(1) 加载和保存JSON数据

    Knockout允许您实现复杂的客户端交互性,但几乎所有Web应用程序还需要与服务器交换数据,或至少将本地存储的数据序列化. 最方便的交换或存储数据的方式是JSON格式 - 大多数Ajax应用程序今天 ...

  8. 面试问题2:给一个5G的大文件,保存的数据为32位的整型,找到所有出现次数超过两次的数字

    问题描述:给一个5G的大文件,保存的数据为32位的整型,找到所有出现次数超过两次的数字 大数据操作: 解决方法一: 依次遍历文件数据, 开始32二进制清0 每次读取一个数,先和二进制位与,如果为0 则 ...

  9. 自动刷新页面为了session不过期

    为了保证在打开页面期间session不过期,估做了一个隐藏Iframe每隔若干秒来刷新一下页面,在隐藏页面给session赋值. <script type="text/javascri ...

随机推荐

  1. Leetcode: Find Right Interval

    Given a set of intervals, for each of the interval i, check if there exists an interval j whose star ...

  2. WebApi 接口测试工具:WebApiTestClient

    文章来源:http://www.cnblogs.com/landeanfen/p/5210356.html 一.WebApiTestClient介绍 1.WebApiTestClient组件作用主要有 ...

  3. struts2笔记4

    1.自定义struts拦截器 应用场景:如果用户登陆后可以访问action中的所有方法,如果用户没有登陆不允许访问action中的方法,并且提示“你没有操作权限” 1)两个页面,一个用户登陆user. ...

  4. MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用

    摘要: 第一阶段1~10篇已经覆盖了MVC开发必要的基本知识. 第二阶段11-20篇将会侧重于专题的讲解,一篇文章解决一个实际问题. 根据园友的反馈, 本篇文章将会先对呼声最高的仓储模式进行讲解. 文 ...

  5. postgresql如何实现回收站机制

         在oracle10G之后:oracle提供一种回收站的机制:即闪回技术.闪回技术通常用于快速简单恢复数据库中出现的认为误操作等逻辑错误.发展到11G之后:回收站更加完善:对在可闪回时间内:数 ...

  6. Object类型与Array类型

    总结--JS中的引用类型: Object类型,Array类型,Boolean类型,Number类型,String类型,Date类型, Function类型,RegExp类型,单体内置对象(Global ...

  7. VS2012下基本类型大小

  8. 理解GRUB2工作原理及配置选项与方法

    GRUB2是借鉴GRUB改写到更加安全强大到多系统引导程序,现在大部分较新的Linux发行版都是使用GRUB2作为引导程序的.GRUB2采用了模块化设计,使得GRUB2核心更加精炼,使用更加灵活,同时 ...

  9. C#的多态性

    参考网址:http://www.cnblogs.com/zhangkai2237/archive/2012/12/20/2826734.html 多态的定义:同一操作作用于不同的对象,可以有不同的解释 ...

  10. Kanzi Studio中的概念

    Kanzi Studio是Kanzi的UI编辑器,功能非常强大.在使用Kanzi Stadio之前,首先要先熟悉编辑器中的概念. Kanzi Studio中主要分project窗格,property窗 ...