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( id,String name) {
19 this.id =20 this.name = name;
21 22
23 getId() {
24 return25 26
27 void setId( id) {
28 29 30
31 String getName() {
32 33 34
35 void setName(String name) {
36 37 38
39 }
? 用户servlet:地址栏输入http://localhost:8080/session/UserServlet进行访问,然后会重定向到showUser.jsp (这样刷新页面的时候就不会访问这个servlet了) com.lizhou.servlet; import java.io.IOException; javax.servlet.ServletException; javax.servlet.annotation.WebServlet; javax.servlet.http.HttpServlet; 7 javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; 9 10 com.lizhou.entity.User; 11 12 13 * 用户servlet 14 15 16 17 class UserServlet extends HttpServlet { 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(125 user.setName("Chiangchou"26 27 //将用户信息保存到session中 28 request.getSession().setAttribute("user",user); 29 保存一个字符串信息 30 request.getSession().setAttribute("message","用户登录成功"31 重定向 33 response.sendRedirect("showUser.jsp");; 34 35 36 37 void doPost(HttpServletRequest request,1)">38 39 40 41 } session监听器:监听session的创建与销毁、向session中添加属性、移除属性、更改属性。 com.lizhou.listener;
javax.servlet.http.HttpSessionAttributeListener;
javax.servlet.http.HttpSessionBindingEvent;
javax.servlet.http.HttpSessionEvent;
javax.servlet.http.HttpSessionListener;
7
9 * session监听器
11 12 class SessionListener implements HttpSessionListener,HttpSessionAttributeListener {
14
15 属性添加时间
16 long addTime;
17
18 @Override
19 sessionCreated(HttpSessionEvent event) {
20 System.out.println("session 创建"23 24 sessionDestroyed(HttpSessionEvent event) {
25 System.out.println("session 销毁"26 27
28 29 attributeAdded(HttpSessionBindingEvent event) {
30 System.out.println("添加属性:"+event.getName());
31 当属性保存的时候保存当前时间
32 addTime = System.currentTimeMillis();
36 attributeRemoved(HttpSessionBindingEvent event) {
37 System.out.println("移除属性:"+38 当属性移除的时候计算属性保存时间
39 long removeTime =40 long t = (removeTime-addTime)/100041 System.out.println("数据保存时间:"+t+"秒"42 43
44 45 attributeReplaced(HttpSessionBindingEvent event) {
46 System.out.println("更改属性:"+47 48
49 }
showUser.jsp 显示用户名 1 <%@ page language="java contentTypetext/html; charset=UTF-8"
2 pageEncodingUTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<htmlheadmeta http-equiv="Content-Type" content="text/html; charset=UTF-8"title>显示用户</body 用户名:【 ${user.name} 】
11 br/>
信息:【 ${message} 】
>
? 准备工作做好了,下面看测试: 首先直接在地址栏输入地址访问UserServlet,在doGet()里会将用户信息保存到session中,重定向到showUser.jsp时,显示用户名和信息,如图:?可以看到,User对象的属性和字符串都能显示。 ? 下面是控制台输出的信息:刚访问servlet后就截图的 ?然后,过了一会,控制台如图: ?可以看到,54秒后,user属性移除了,message没有移除,session并没有销毁哦!!!然后刷新页面显示:这就是我们常见到的情况了.... ? 然后,百度大部分说设置session过期时间长一点:但是没有效果 1 <!-- 设置session失效时间(单位:分) -->
2 session-config3 session-timeout>304 >
然后还有一种方法:在根目录下放一个refresh.jsp文件,内容如下:主要是第6行代码,每隔一秒刷新一下,链接到自己 ="refresh"="1; url=refresh.jsp"></>
然后在显示数据的页面(showUser.jsp)加上一句代码:<iframe width=0 height=0 src="refresh.jsp"></iframe> 目的是不断请求服务器,我的理解是服务端以为客户端一直在使用这个对象,就不会移除这个数据了.... 这样虽然达到了目的,但有很大的弊端,而且治标不治本:一直请求服务器消耗服务器资源是肯定的了,而且浏览器的刷新图标会一直跳,看着很不爽的... ? ?***************************************************************************************************************** ?最后,看解决办法:只需要将User实现序列化接口Serializable即可,如下: java.io.Serializable;
4
9 class User Serializable {
13
15
17
21 22 24
25 //getter/setter方法26
27 }
? 将要保存到session中的对象实现序列化接口Serializable,这样用户数据就一直保存在session里了,不管你怎么刷新,除非session销毁,数据一直都在!!! 那么原因是什么呢?下面是我百度的一段: 【Object serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原来的对象。 ? 附上测试代码:session数据丢失测试代码 ?OK!!! ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |