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

Jsf 2 优雅地处理会话超时的方法是什么?,jsf-2,Jsf 2,问题是:我在申请表的某一页上,离开了一会儿。返回并单击一个链接,我会收到一条“无法恢复viewID”消息。点击刷新时也是如此 我可以启动新会话,但我必须手动编辑URL,如下所示: 活动地址窗口: http://localhost:8080/myapp/index.xhtml?windowId=e9d 进入 然后建立一个新会话,用户必须再次登录,这就是我想要的 在研究如何处理这个问题时,我看到了很多“解决方案”,它们基本上通过使用客户端Javascript定期发送请求来保持会话的活动性。就我个人

问题是:我在申请表的某一页上,离开了一会儿。返回并单击一个链接,我会收到一条“无法恢复viewID”消息。点击刷新时也是如此

我可以启动新会话,但我必须手动编辑URL,如下所示:

活动地址窗口:

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

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

在研究如何处理这个问题时,我看到了很多“解决方案”,它们基本上通过使用客户端Javascript定期发送请求来保持会话的活动性。就我个人而言,我不认为这是一个理想的解决方案。 我想要的是,当会话超时时,对任何非公共页面的所有后续请求都需要定向到index.xhtml。对不需要登录的页面的引用应使用新的会话对象完成。最好只使用JSF2定义的工具来处理这个问题,但如果需要的话,我不介意编写一个Servlet过滤器


有人能提供我错过的操作指南的链接吗?

过滤器中进行操作,是的。您可以使用来检查客户端是否发送了会话cookie,并检查会话cookie是否仍然有效(即会话在服务器端尚未过期):


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

我正在应用程序级别处理用户身份验证。有一个名为Login的@SessionScoped bean,其属性之一是用户对象,如果用户未登录,则该对象为null。我想我知道如何从过滤器中获取托管bean,这样我就可以相应地修改您的示例代码。我是否可以假设sendRedirect()调用将中止对请求的任何进一步处理?是的,它将中止。只有通过
chain.doFilter()
继续请求/响应时,才会调用所有其他筛选器/servlet(以及
FacesServlet
)。相关:这个解决方案遇到了一些问题,因为我需要访问会话范围的对象来确定身份验证状态。在过滤器中访问FacesContext对象充其量是痛苦的。是否可以/更好地使用相位监测器来代替?我在这里查看您的网页:过滤器在
FacesServlet
运行之前运行。它还没有创建
FacesContext
。只需将会话范围的托管bean作为
HttpSession
属性获取即可。JSF将它们存储在那里。另请参见我前面评论中的“相关”链接,以了解具体的代码示例。
http://localhost:8080/myapp/index.xhtml
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);
    }
}