优雅处理会话超时的方法是什么?

时间:2011-10-17 16:21:12

标签: jsf-2

问题:我在我的应用程序的某个页面上并且离开了一段时间。返回并单击链接,我收到“无法恢复viewID”消息。点击刷新时也一样。

我可以开始一个新会话,但我必须按如下方式手动编辑URL:

活动地址窗口:

http://localhost:8080/myapp/index.xhtml?windowId=e9d

http://localhost:8080/myapp/index.xhtml

然后建立一个新会话,用户必须再次登录,这就是我想要的。

在研究如何处理这个问题时,我看到很多“解决方案”基本上通过使用客户端Javascript定期发送请求以保持会话处于活动状态来使会话保持活动状态。我个人认为这不是一个理想的解决方案。

我想要的是当会话超时时,对任何非公共页面的所有后续请求都需要定向到index.xhtml。对不需要登录的页面的引用应该使用新的会话对象。最好只使用JSF 2定义的工具来处理,但我不介意编写Servlet过滤器,如果需要的话。

任何人都可以提供我错过的操作方法的链接吗?

1 个答案:

答案 0 :(得分:4)

Filter中执行,是的。您可以使用HttpServletRequest#getRequestedSessionId()检查客户端是否已发送会话cookie,并HttpServletRequest#isRequestedSessionIdValid()检查它是否仍然有效(即服务器端的会话尚未过期):

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletRequest res = (HttpServletResponse) response;

    if (req.getRequestedSessionId() != null && !req.isRequestedSessionIdValid()) {
        res.sendRedirect(req.getContextPath() + "/index.xhtml");
    } else {
        chain.doFilter(request, response);
    }
}

但是,这又带来了另一个问题,您如何过滤登录用户?如果会话已过期,则用户不再登录,对吧?如果用户已登录,您也可以只检查过滤器。