【问题标题】:Redirecting on session timeout in JSF-Richfaces-facelet在 JSF-Richfaces-facelet 中重定向会话超时
【发布时间】:2009-09-17 11:44:27
【问题描述】:

我正在使用 JSF 和 RichFacecs 创建一个 Web 门户。我想在会话超时时将用户重定向到登录页面。我试图在会话到期/注销阶段抛出 SecurityException,如下所示

<error-page>
    <exception-type>java.lang.SecurityException</exception-type>
    <location>/Login.jsf</location>
</error-page>

但这对我不起作用。哪种是正确的处理方法?

【问题讨论】:

    标签: jsf richfaces facelets


    【解决方案1】:

    应该这样做:

    <error-page>
        <exception-type>javax.faces.application.ViewExpiredException</exception-type>
        <location>/sessionExpired.jsf</location>
    </error-page>
    

    【讨论】:

    • 感谢您的回答。我试过这个,它不适用于 ajax 请求
    • 您能展示一下您是如何实现会话过期页面的吗?重要的是您使用的重定向功能也不会超时=)
    • 我在会话到期时重定向登录页面。我得到了另一个可行的解决方案。现在我正在像 FacesContext.getCurrentInstance().getExternalContext().redirect("login.jsf") 这样的支持 bean 中重定向。这是正确的方法吗?
    • 我认为这种方法没有任何问题。我很高兴你找到了一种可行的方法。
    • 非常感谢克里斯的支持
    【解决方案2】:

    您应该在您的 web.xml 中设置一个超时并注册一个超时过滤器,如以下线程所示:Auto-logout in JSF Application 在 ajax 的情况下,您的重定向必须这样做:

        String facesRequestHeader = httpServletRequest
                .getHeader( "Faces-Request" );
    
        boolean isAjaxRequest = facesRequestHeader != null
                && facesRequestHeader.equals( "partial/ajax" );
    
        if( isAjaxRequest )
        {
                String url = MessageFormat.format( "{0}://{1}:{2,number,####0}{3}",
                request.getScheme(), request.getServerName(),
                request.getServerPort(), timeoutPath );
    
                PrintWriter pw = response.getWriter();
                    pw.println( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" );
                pw.println( "<partial-response><redirect url=\"" + url
                + "\"></redirect></partial-response>" );
                pw.flush(););
        }
        else
        {
            httpServletResponse.sendRedirect( timeoutPath );
        }
    

    【讨论】:

      【解决方案3】:

      解决方法是使用Richfaces自己的session expired event

      将此添加到容易过期的页面:

      <a4j:region>
       <script language="javascript">
       A4J.AJAX.onExpired = function(loc, expiredMsg){
       alert('expired!');
       window.location = "/login.jsf";
       }
       </script>
      </a4j:region>
      

      更多信息可以在 RichFaces 文档中找到: http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/ArchitectureOverview.html#SessionExpiredHandling

      【讨论】:

        【解决方案4】:

        我在会话到期后发出 A4J 请求时遇到了一些问题。 我把这个

        <context-param>
            <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
            <param-value>true</param-value>
        </context-param>
        

        在我的 web.xml 中,对我来说它解决了问题。

        【讨论】:

          【解决方案5】:

          另一种解决方案是创建扩展 ViewHandler 的 CustomViewHandler 并覆盖 restoreView 方法

          @Override
          public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
          /**
           * {@link javax.faces.application.ViewExpiredException}. This happens only  when we try to logout from timed out pages.
           */
              UIViewRoot root = null; 
              root = parent.restoreView(facesContext, viewId);
              if(root == null) {          
                  root = createView(facesContext, viewId);
              }
              return root;
          }
          

          然后你需要将它添加到你的 faces-config.xml

          <view-handler>com.demo.CustomViewHandler</view-handler>
          

          这会阻止你得到 ViewExpiredException 的

          【讨论】:

          • 注意:我认为“父”应该是“超级”,也可以添加到 createView 中。我还建议扩展像 com.sun.faces.application.ViewHandlerImpl 这样的 ViewHandler 的实现,这样您就不需要重写所有的 ViewHandler 类。
          猜你喜欢
          • 1970-01-01
          • 2012-04-25
          • 2010-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-14
          • 2013-03-29
          • 1970-01-01
          相关资源
          最近更新 更多