如何在Struts2中设置Session超时?编写的拦截器代码无法生效
Struts2会话超时拦截器修复方案
原代码问题分析
你写的拦截器逻辑存在核心错误:
- 使用
session.isEmpty()判断会话超时完全不准确。当原生HttpSession超时后,调用getSession()会自动创建一个新的空会话,此时isEmpty()为true,但这并不是“会话过期”的场景——我们需要检测的是用户已登录但会话失效,而非新用户的空会话。
正确实现步骤
1. 先在web.xml配置会话超时时间(基础配置)
这是会话超时的根本设置,单位为分钟:
<session-config> <!-- 设置会话30分钟后超时,可根据需求调整 --> <session-timeout>30</session-timeout> </session-config>
2. 修改拦截器逻辑,检测登录态标识
拦截器需要判断会话中是否存在用户登录后的标识(比如loggedInUser,根据你的业务调整),而非会话是否为空:
import java.util.Map; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class SessionInterceptor extends AbstractInterceptor { private static final long serialVersionUID = 1L; @Override public String intercept(ActionInvocation invocation) throws Exception { Map<String, Object> session = invocation.getInvocationContext().getSession(); // 检查会话中是否存在登录用户标识 Object loggedInUser = session.get("loggedInUser"); // 无登录标识,说明会话过期或未登录,跳转到超时页面 if (loggedInUser == null) { return "session"; } // 有登录态,继续执行后续逻辑 return invocation.invoke(); } }
3. 在struts.xml中注册并启用拦截器
需要将自定义拦截器加入拦截器栈,并配置全局结果:
<struts> <package name="default" extends="struts-default"> <interceptors> <!-- 注册自定义会话拦截器,替换为你的实际包路径 --> <interceptor name="sessionInterceptor" class="com.yourpackage.SessionInterceptor"/> <!-- 自定义拦截器栈:包含默认栈+自定义拦截器 --> <interceptor-stack name="customStack"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="sessionInterceptor"/> </interceptor-stack> </interceptors> <!-- 设置默认使用自定义拦截器栈 --> <default-interceptor-ref name="customStack"/> <!-- 全局结果:对应拦截器返回的"session",替换为你的超时页面路径 --> <global-results> <result name="session" type="redirect">/sessionTimeout.jsp</result> </global-results> </package> </struts>
4. 登录时存入会话标识
确保在用户登录成功后,将登录标识存入Session:
// 在登录Action的成功处理方法中 Map<String, Object> session = ActionContext.getContext().getSession(); session.put("loggedInUser", userInfo); // userInfo为登录后的用户对象或用户名
内容的提问来源于stack exchange,提问作者Raja Vallapan
相关产品推荐
相关产品推荐

