今天写了一个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;
}
}
分享到:
相关推荐
在Struts2中,一个Action类对应一个用户请求,处理用户的请求数据,执行相应的业务逻辑,并通过返回值(Result)来决定页面跳转。 2. **Result**:Result负责处理Action执行后的结果,决定如何展示给用户。它可以是...
总之,Struts2的所有包和配置文件构成了一个功能强大的MVC框架,通过`web.xml`和`struts.xml`的合理配置,可以实现高效、灵活的Web应用开发。理解并熟练运用这些核心组件和配置,对于提升Java Web开发的效率和质量至...
7. **Struts2 Action返回值**:在Action中,你可以将生成的报表作为流返回,然后在Struts2的Result类型中配置为stream或file,这样用户就可以在浏览器中查看或下载报表。 8. **错误处理**:别忘了在代码中添加适当...
2. 合理使用单向一对多关联。 3. 避免一对一关系,用多对一代替。 4. 配置对象缓存,避免使用集合缓存。 5. 一对多集合使用Bag,多对多集合使用Set。 6. 继承类使用显式多态。 7. 减少表字段数量,增加表关联,利用...
Struts2和JSON的结合是Web开发中常见的一种技术组合,尤其在构建动态、数据交互丰富的应用程序时。本文将深入探讨这两个技术如何协同工作,...通过合理配置Action和使用合适的库,你可以轻松地实现这一功能强大的组合。
- 尽管拦截器提供了强大的功能,但过度使用或不合理的拦截器配置可能会对性能造成影响。尽量减少不必要的拦截器,避免在性能敏感的操作上使用拦截器。 9. **测试与调试**: - 在开发和调试过程中,要充分测试拦截...
合理使用空行来分隔不同的代码段,增强可读性。 **8.2 空格** 正确使用空格来提高代码的可读性,例如在运算符前后添加空格。 #### 八、命名规范 文档中虽然没有具体列出命名规范,但是通常推荐使用有意义的变量...
OGNL(Object-Graph Navigation Language)是Struts2中使用的表达式语言,用于访问Java对象的属性和调用方法,增强了视图层的表达能力和灵活性。 #### 表达式语言主要好处 OGNL的主要好处包括简洁的语法、强大的...
3. **命名空间的合理分配**:根据项目的特点和团队协作的需求,合理地规划命名空间,确保不同模块之间的 Action 名称不发生冲突。 #### 五、总结 通过本文的学习,我们不仅了解了 Struts 2 在命名规范方面的基本...
通过Action的返回值,Struts2能够自动选择对应的模板来生成响应。此外,Struts2还集成了Tiles框架,可以方便地创建和管理复杂的页面布局。 安全性方面,Struts2提供了防止XSS(跨站脚本攻击)和CSRF(跨站请求伪造...
- **Action方法返回值不明确**:确保Action的方法返回值与struts.xml中的result配置匹配。例如,通常"success"表示成功跳转,"input"表示表单验证失败。 3. **视图渲染问题**: - **JSP页面无法显示**:检查JSP...
8. **优化性能**:合理使用Ajax避免不必要的请求,结合Struts的缓存机制和分页功能,进一步提升应用性能。 在实际开发中,结合使用Ajax框架(如jQuery)和Struts框架,可以创建高性能、用户友好的Web应用。通过深入...
通过合理使用注解,开发者可以更专注于业务逻辑,而不是繁琐的配置工作。然而,值得注意的是,虽然注解方便,但在大型项目中,XML配置仍具有其灵活性和可扩展性,两者结合使用可以达到最佳效果。
在Web开发过程中,特别是在使用Struts框架进行开发时,经常会遇到字符编码的问题,尤其是中文字符的乱码问题。本文将详细介绍Struts中常见的乱码现象,并提供具体的解决方案。 #### 二、乱码现象分析 在Web应用中...
优化策略包括减少不必要的JSP标签使用,利用缓存机制,以及合理使用Tiles框架来组织页面。 通过上述问题的解决,我们可以更好地理解和掌握Struts1.2中的taglib标签,提升项目开发的效率和质量。在实际开发中,遇到...
2. **JSON结果类型**:Struts2支持配置JSON结果类型,可以将Action的返回值转化为JSON格式,然后通过AJAX请求获取并解析,更新页面的特定部分。 3. **JQuery插件**:Struts2与jQuery结合,可以使用jQuery的AJAX方法...
5.5 **Struts标记库使用**:熟练掌握并合理使用Struts标记库,提高前端页面的开发效率和可维护性。 六、注释:清晰的代码文档化 6.1 **注释格式**:遵循Javadoc标准,为类、方法、变量添加详细注释,提高代码的...
Tiles框架通常与Struts框架结合使用,用来定义页面布局和组织页面结构。 **11. Struts1.x和Struts2的区别** - **架构差异**:Struts2采用了拦截器栈模型,而Struts1则采用了传统的MVC模式。 - **配置方式**:...