You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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从会话层面控制,更适合生产环境:

  1. 创建会话超时过滤器类
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() {}
}
  1. 若未使用@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 14:54:21