Java JSF项目闲置超时后如何重定向至login.xhtml页面?
JSF项目实现闲置自动重定向到登录页的方案
一、前端JavaScript实现(快速易用)
在项目的通用模板页面(如template.xhtml,所有页面都会引用的母版页)中添加以下脚本,可自定义闲置超时时长:
<script type="text/javascript"> // 超时时间设置:30分钟 = 1800000毫秒 const IDLE_TIMEOUT = 1800000; let timeoutTimer; // 重置闲置计时器 function resetIdleTimer() { clearTimeout(timeoutTimer); timeoutTimer = setTimeout(redirectToLogin, IDLE_TIMEOUT); } // 跳转至登录页 function redirectToLogin() { window.location.href = '#{request.contextPath}/login.xhtml'; } // 监听用户交互事件(点击、滚动、按键) document.addEventListener('click', resetIdleTimer); document.addEventListener('scroll', resetIdleTimer); document.addEventListener('keydown', resetIdleTimer); // 页面加载时启动计时器 window.onload = resetIdleTimer; // 监听JSF AJAX请求完成事件,避免AJAX操作不触发计时器重置 jsf.ajax.addOnEvent(function(event) { if (event.status === 'success') { resetIdleTimer(); } }); </script>
二、后端Filter实现(安全可靠)
前端方案可被篡改,后端Filter从会话层面控制,更适合生产环境:
- 创建会话超时过滤器类
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebFilter("/*") // 拦截所有请求 public class SessionIdleFilter implements Filter { // 闲置超时时间:30分钟 = 1800秒 private static final int IDLE_SECONDS = 1800; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(false); // 放行登录页和JSF静态资源 String requestPath = req.getRequestURI(); if (requestPath.contains("/login.xhtml") || requestPath.contains("/javax.faces.resource/")) { chain.doFilter(request, response); return; } if (session != null) { Long lastAccessTime = (Long) session.getAttribute("lastAccessTimestamp"); long currentTimestamp = System.currentTimeMillis() / 1000; if (lastAccessTime == null) { session.setAttribute("lastAccessTimestamp", currentTimestamp); chain.doFilter(request, response); } else { long idleDuration = currentTimestamp - lastAccessTime; if (idleDuration >= IDLE_SECONDS) { // 超时则销毁会话并跳转登录页 session.invalidate(); res.sendRedirect(req.getContextPath() + "/login.xhtml"); } else { // 更新最后访问时间 session.setAttribute("lastAccessTimestamp", currentTimestamp); chain.doFilter(request, response); } } } else { // 无有效会话直接跳转登录页 res.sendRedirect(req.getContextPath() + "/login.xhtml"); } } @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void destroy() {} }
- 若未使用
@WebFilter注解,需在web.xml中配置过滤器:
<filter> <filter-name>SessionIdleFilter</filter-name> <filter-class>com.yourpackage.SessionIdleFilter</filter-class> </filter> <filter-mapping> <filter-name>SessionIdleFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
额外注意事项
- 建议两种方案结合使用:前端及时提示跳转,后端做安全兜底。
- 需保证Filter的超时时间与
web.xml中会话超时配置一致:
<session-config> <session-timeout>30</session-timeout> <!-- 单位:分钟 --> </session-config>
- 若项目中有自定义登录态标识(如
loggedUser),可在Filter中增加该属性的判断,进一步限制未登录用户访问。
内容的提问来源于stack exchange,提问作者Anas Abdeljalil
相关产品推荐
相关产品推荐

