今天写了一个SessionListener来监听session的创建和销毁情况,有意外收获,发现系统的一个bug:
当关闭浏览器时,容器会销毁当前session,而后新建一个同sessionId的session。
经过分析,发现session的销毁是由退回操作时应用程序进行的失效操作引发。而后session的新建是由应用程序调用了logout操作后struts的返回值想后台又发起了一个请求导致的session的新建,而该session只能等待session过期才能自动销毁了。
这时可采用关闭窗口和logout有区别对待即可,logout有返回值,而关闭窗口时无返回值。或者在主页添加
<%@ page session="false"%>
禁用session,也可以解决。
附:SessionListener的类:
package com.shuidexiongdi.listener;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MySessionListener implements HttpSessionListener {
private final static Map<String,HttpSession> sessionMaps = Collections.synchronizedMap(new HashMap<String, HttpSession>()); //存放session的集合类
private final static Map<String,SessionLive> sessionLiveMaps = Collections.synchronizedMap(new HashMap<String, SessionLive>());
private final static Logger logger = LoggerFactory.getLogger(MySessionListener.class);
public void sessionCreated(HttpSessionEvent sessionEvent) {
HttpSession currentSession = sessionEvent.getSession();
sessionMaps.put(currentSession.getId(), currentSession);
SessionLive sessionLive = new SessionLive(currentSession.getId());
sessionLive.setStartTime(new Date());
sessionLiveMaps.put(currentSession.getId(), sessionLive);
logger.info("session created: " + sessionLive.toString());
logger.info("\ncurrentSession Created Time: " + currentSession.getCreationTime());
logger.info("\ncurrentSession isNew: " + currentSession.isNew());
}
public void sessionDestroyed(HttpSessionEvent sessionEvent) {
HttpSession currentSession = sessionEvent.getSession();
SessionLive sessionLive = null;
if(sessionMaps.containsKey(currentSession.getId()) && sessionLiveMaps.containsKey(currentSession.getId())) {
HttpSession session = sessionMaps.get(currentSession.getId());
session.invalidate();
sessionMaps.remove(currentSession.getId());
session = null;
sessionLive = sessionLiveMaps.get(currentSession.getId());
sessionLive.setEndTime(new Date());
}
logger.info("sessin destroyed:" + sessionLive.toString());
}
}
class SessionLive {
private String sessionId;
private Date startTime;
private Date endTime;
SessionLive(String sessionId) {
this.sessionId = sessionId;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getStartTime() {
return startTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Date getEndTime() {
return endTime;
}
public String toString() {
return "\nsessionId: " + sessionId +"\nstartTime: " + startTime + " \nendTime: " + endTime;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getSessionId() {
return sessionId;
}
}