struts返回值的不合理使用

本文通过自定义SessionListener发现了浏览器关闭时系统重复创建session的bug,并提供了两种解决方案:一是区分关闭窗口与logout操作,二是禁用主页session。同时,附上了自定义监听器的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天写了一个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;
	}
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值