当前位置:首页 > 开发 > 编程语言 > 加密解密 > 正文

sessionDestroyed执行时间的奇怪问题

发表于: 2010-05-25   作者:酷的飞上天空   来源:转载   浏览:
摘要: 问题描述: 用户登陆后转到list.jsp页面,此页面不停向服务器请求数据。用户的登录名保存到session和servletContext的用户列表中一个list。当用户session失效的时候从用户列表中删除用户。 问题是: 虽然不停向服务器发送数据,但还是会在不到一分钟的时间内调用sessionDestroyed方法,难道此方法不是在session失效的时候才被调用?  

问题描述:

用户登陆后转到list.jsp页面,此页面不停向服务器请求数据。用户的登录名保存到session和servletContext的用户列表中一个list。当用户session失效的时候从用户列表中删除用户。

问题是:

虽然不停向服务器发送数据,但还是会在不到一分钟的时间内调用sessionDestroyed方法,难道此方法不是在session失效的时候才被调用?

 

下面贴出完整代码。

login.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>login</title>
</head>
<body style="text-align: center;">

	<p style="margin-top: 200px;" />
	<p>${error }</p>
	<form action="login" method="post">
		用户名:<input type="text" name="name"/>
		<p/>
		<input type="submit"/>
	</form>
</body>
</html>

 

 LoginServlet

public class LoginServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		String name = req.getParameter("name");
		List<String> list;
		if(name==null||name.equals("")){
			req.setAttribute("error", "登录名不能为空!");
			req.getRequestDispatcher("login.jsp").forward(req, resp);
			return;
		}
		//从ServletContext中取得已登录用户信息的容器,一个list
		Object o = getServletContext().getAttribute("list");
		if(o==null){
			//如果没有,则创建一个并放入ServletContext
			list = new ArrayList();
			getServletContext().setAttribute("list", list);
		}
		else {
			//有则返回
			list = (List<String>)o ;
		}
		//如果当前登陆用户有重名的则,无法登陆
		if(list.contains(name)){
			req.setAttribute("error", "用户已存在!");
			req.getRequestDispatcher("login.jsp").forward(req, resp);
			return;
		}
		//将登陆用户放入ServletContext中的list
		list.add(name);
		getServletContext().setAttribute("list", list);
		//将当前用户的用户名放入session
		HttpSession session = req.getSession();
		Logger.getLogger(this.getClass().getName()).info("原始会话超时时间为:"+session.getMaxInactiveInterval());
		session.setMaxInactiveInterval(5); //设置当前会话的失效时间,单位是秒。即5秒不回应则判定离线
		session.setAttribute("name", name);
		Logger.getLogger(this.getClass().getName()).info("设定会话超时时间为:"+session.getMaxInactiveInterval());
		
		req.setAttribute("list", list);

		req.getRequestDispatcher("list.jsp").forward(req, resp);
		
	}
}

 list.jsp ,用到了jquery进行Ajax调用

  

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<!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>login</title>
<style type="text/css">
	.left{
		width: 200px;
		height: 600px;
		float: left;
		border: dashed 1px black;
	}
	.right{
		width: 600px;
		height: 600px;	
		margin-left: 220px;
		border: dotted 1px black;
		overflow: scroll;
	}
</style>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript">
	//如果返回类型定义为json,则无法重复执行,所以只能自己eval了。原因是jquery1.4解析json格式比较严格,这里返回的是不严格的json格式,致使解析失败。解决方法:1.返回严格的json格式数据2.自己eval生成json对象
	$(function(){
		function getText(){
			$.post("control",function(data){
				var json = eval("("+data+")");
				//返回在线用户数组
				var list = json.list;
				var date = json.date; //服务器端返回的日期
				var $left = $(".left");
				var nameList = "";  //构造用户在线字符串形式,方便添加进html
				for(var i in list){
					nameList = nameList+"<li>"+list[i]+"</li>"
				}
				$left.empty().html("当前用户列表:<br/><ul>"+nameList+"</ul>");
				$(".right").append("服务器端传来数据:"+date+'<br/>');
				//继续请求服务器
				getText();
			});
		}
		//开始执行
		getText();
	});
</script>
</head>
<body>
<div class="left">
当前用户列表:
<p></p>
<ul>
	<%
		List<String> list = (List<String>)request.getAttribute("list");
		for(String s:list){
	%>
		<li><%=s %></li>
		<%} %>
</ul>
</div>
<div class="right">

</div>
</body>
</html>

   ControlServlet

 

public class ControlServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String text;
		List<String> list;
		StringBuilder sb = new StringBuilder();
		text = simpleDateFormat.format(new Date());
		//取得在线的列表
		Object o =getServletContext().getAttribute("list");
		if(o==null) list = null;
		else list = (List<String>)o;
		
		//构造返回的String, json格式
		sb.append("{list:[");
		if(list==null){
			//一个空的数组
			sb.append("],");
		}else{
			for(int i=0;i<list.size();i++){
				sb.append("\"");
				sb.append(list.get(i));
				sb.append("\"");
				//如果是最后一个则不添加 ','
				if(i!=list.size()-1) sb.append(",");
			}
			sb.append("],");
		}
		//把服务器返回的时间添加入json
		sb.append("date:").append("\"").append(text).append("\"");
		sb.append("}");
		
		resp.setCharacterEncoding("UTF-8");
		PrintWriter out = resp.getWriter();
		//停留一秒后,然后再向客户端输出。如果不停留,则浏览器会不停处理,可能崩溃。
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			//
		}
		//返回组装好的json字符串形式
		out.print(sb.toString());
		//Logger.getLogger(this.getClass().getName()).info("服务器段返回json的字符串为:\n"+sb.toString());
	}

}

 

SessionListener

public class SessionListening implements HttpSessionListener {

	@Override
	public void sessionCreated(HttpSessionEvent se) {
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent se) {
		//从session中取得登陆的用户名
		Object o = se.getSession().getAttribute("name");
		//如果未登录则返回
		if(o==null) return;
		String name = (String)o;
		//从ServletContext中获得登陆用户的容器
		Object ob = se.getSession().getServletContext().getAttribute("list");
		//如果容器为null,则返回
		if(ob==null) return;
		List<String> list = (List<String>)ob;
		//从list中移除当前用户
		if(list.contains(name)) list.remove(name);
		//把改变后的list重新放入ServletContext
		se.getSession().getServletContext().setAttribute("list", list);
		Logger.getLogger("session").info("用户"+name+",退出!");
		
	}

}

 

web.xml

  <listener>
  		<listener-class>test.servlet.SessionListening</listener-class>
  </listener>
  
  <servlet>
  		<servlet-name>login</servlet-name>
  		<servlet-class>test.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  		<servlet-name>login</servlet-name>
  		<url-pattern>/login</url-pattern>
  </servlet-mapping>
  <servlet>
  		<servlet-name>control</servlet-name>
  		<servlet-class>test.servlet.ControlServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  		<servlet-name>control</servlet-name>
  		<url-pattern>/control</url-pattern>
  </servlet-mapping>

 

虽然设置session的失效时间在5秒,但是总是在大概1分钟的时候调用sessionDestroyed方法。

以上为全部工程文件,

等待高手解答

sessionDestroyed执行时间的奇怪问题

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
js代码如下: Ext.onReady(function(){ var tabs= new Ext.TabPanel({ applyTo:'tab', //renderTo:Ex
最近在做一个弹出window 中套tabpanel的页面,是两个页面,一个window的页面一个tabpanel的页面,
#include <stdio.h> #include <string.h> //#include <iostream> #include <m
1,寻路算法 http://qiao.github.io/PathFinding.js/visual/ 5,linux系统奇怪问题 5.1 命令行输入
最近开始研究struts2,一开始就遇到莫名其妙的问题 在配置struts2时,使用的是Tomcat6.0服务器,按书
JLSINT用了快一年了,结合Jekins来使用,很是方便。配置文件什么的,只要拷贝拷贝就可以了的。 不过
今天整C#的DAO层,我用的2013, 用的4.0的.NetFramework刚刚创建完Helper就出现异常 + Connection “
JLSINT用了快一年了,结合Jekins来使用,很是方便。配置文件什么的,只要拷贝拷贝就可以了的。 不过
一次奇怪的问题定位过程 简介 遇到的很奇怪的一个问题、在做数据统计时、先将测试数据存放到表中、
今天在做一个项目过过程中遇到了一个问题,很是纠结,错误输出大概是这样的: FTH: (6140): ***Faul
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号