Java HttpSession超时后重定向

Java HttpSession超时后重定向,java,jsf,jakarta-ee,timeout,Java,Jsf,Jakarta Ee,Timeout,我已经看了很多关于这个话题的帖子,但是没有一个适合我的解决方案 我正在使用JavaEE6和JSF2.0(作为7.1部署在JBoss上) 在我的web.xml中,我有: <session-config> <session-timeout>1</session-timeout> </session-config> 在web.xml中,我尝试了 <filter-mapping> <filter-

我已经看了很多关于这个话题的帖子,但是没有一个适合我的解决方案

我正在使用JavaEE6和JSF2.0(作为7.1部署在JBoss上)

在我的
web.xml
中,我有:

    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
web.xml
中,我尝试了

<filter-mapping>
    <filter-name>TimeOutFilter</filter-name>
    <url-pattern>*.xhtml</url-pattern>
</filter-mapping>
我无法重定向到特定页面。当我想重定向用户时,我通常使用
FacesContext
中的
NavigationHandler
,但在这种情况下,没有
FacesContext
FacesContext.getCurrentInstance()
返回
null

根据这一点,HttpListener无法重定向用户,因为它不是请求的一部分

问题


解决这个问题最好的办法是什么?要使上述两种方法之一发挥作用,我可以做些什么?

只要客户端没有发送HTTP请求,就不能发送HTTP响应。就这么简单。HTTP就是这样工作的。如果任何一个网站能够在没有客户端请求的情况下,毫不犹豫地推送HTTP响应,那么互联网看起来就会大不相同

如果您基本上只有一个页面的webapp(因此,您实际上使用的不是会话范围,而是视图范围),那么基于JavaScript的心跳(基于客户端键盘/鼠标活动,如asanswered)或meta
refresh
header,如asanswered)将是解决方案,但是,如果您在同一个会话中在多个选项卡/窗口中打开页面,这将无法很好地工作

理论上,Websockets是将内容推送到客户端的正确解决方案,但这反过来又需要一个活动会话。鸡蛋问题。而且,它在目前仍在相对广泛使用的旧浏览器中不起作用,因此它目前应该仅用于渐进增强


最好只定义一个错误页面,该页面处理终端用户在会话过期时调用操作的情况。另请参见。

我知道您正在使用java-EE6和JSF,但如果您可以尝试使用JSP代码或将下面的代码转换为在servlet中工作的代码。假设您使用用户名检查会话,在web.xml文件中设置会话超时后。请注意,JSP代码和servlet代码类似。 用于验证会话的代码可能如下所示。(JSP格式) 如果用户名用作数据库中的主键

 <%
    String un = (String)session.getAttribute("un");

    if(un == null){
   response.sendRedirect(login page);
   return;
}else{
      code to process login form
}
    %>

在HttpSessionListerner中,您不能向用户发送任何响应。实现这一点的一个好方法是使用轮询,浏览器定期发送HTTP请求并立即接收响应。
有很多方法可以做到这一点:

  • 您可以使用普通的旧javascript进行轮询:这将在跨浏览器环境中工作

    函数刷新(){

    }

    设置超时(刷新,5000)

  • 您可以使用Web套接字。Web套接字规范显示在以下链接中:


  • 您可以使用过滤器并执行以下测试:

    HttpSession session = request.getSession(false);
    if(session != null && !session.isNew()) {
        chain.doFilter(request, response);
    }
     else {enter code here
        response.sendRedirect("/login.jsp");
     }
    

    相关:@LuiggiMendoza:很有趣,谢谢。虽然我从未见过
    ViewExpiredException
    ,但如果可能的话,我想重定向到登录页面,而用户无需单击任何内容。您需要在客户端进行某种形式的轮询,以触发服务器端的302。心跳…也相关:。@BalusC:所有这些页面都会被重定向到登录页面,不是吗?一旦到了那里,他们就会停止投票。如果一个页面执行日志记录,另一个“未注销”页面应该使用新会话cookie并保持登录。我现在明白我的误解了。我需要的不是自动重定向用户,而是让用户知道会话超时后是否执行了操作。
    public void sessionDestroyed(HttpSessionEvent se) {
    }
    
     <%
        String un = (String)session.getAttribute("un");
    
        if(un == null){
       response.sendRedirect(login page);
       return;
    }else{
          code to process login form
    }
        %>
    
    String un = (String)session.getAttribute("un");
    if(un == null){
       response.sendRedirect(loginPage);
    }
    
    // make Ajax call here, inside the callback call:
    
    setTimeout(refresh, 5000);
    
    // ...
    
    // initial call, or just call refresh directly
    
    HttpSession session = request.getSession(false);
    if(session != null && !session.isNew()) {
        chain.doFilter(request, response);
    }
     else {enter code here
        response.sendRedirect("/login.jsp");
     }