3 Replies Latest reply on Jan 20, 2009 6:58 PM by norman

    URL rewriting broken for view-id of redirects in exceptions

    stephen

      My /login.xhtml has a rewrite pattern defined in its page definition:


      <page view-id="/login.xhtml" action="#{authenticator.enterLogInPage}">
          <rewrite pattern="/log-in"/>
      </page>
      



      I also tried to configure an exception handler for the ViewExpiredException:


      <exception class="javax.faces.application.ViewExpiredException">
          <redirect view-id="/login.xhtml">
              <message severity="WARN">Your session has timed out.</message>
          </redirect>
      </exception>
      



      Unfortunately this is not working at all. The redirect generates an login.seam URL, but should of course generate log-in instead.


      I researched this issue and I think I found the culprit:
      This is the chain of  servlet filters that Seam uses:


      org.jboss.seam.web.HotDeployFilter
      org.jboss.seam.web.LoggingFilter
      org.jboss.seam.web.Ajax4jsfFilter
      org.jboss.seam.web.RedirectFilter
      org.jboss.seam.web.ExceptionFilter
      org.jboss.seam.web.MultipartFilter
      org.jboss.seam.web.IdentityFilter
      org.jboss.seam.web.ContextFilter
      org.jboss.seam.web.RewriteFilter: response=RewritingResponse
      



      The rewriting happens in the RewritingResponse that is only active while the RewriteFilter is active on the chain.
      When the ExceptionFilter recovers after catching an exception, it uses its own response object, that is no longer wrapped by the RewritingResponse, so no rewriting takes place.


      A workaround for me was to replace the Exception filter with my own component (thanks for the overridable component definitions) and wrap the response myself:


      MyExceptionFilter.doFilter():


              try {
                  chain.doFilter(request, response);
              }
              catch (Exception e) {
                  log.warn("handling uncaught exception", e);
                  log.warn("exception root cause", Exceptions.getCause(e));
      
                  // ADDED THIS LINE:
                  response = new RewritingResponse((HttpServletRequest) request, (HttpServletResponse)response, getAllPatterns()); 
                  endWebRequestAfterException((HttpServletRequest) request, (HttpServletResponse) response, e);
              }
      



      (I had to copy the getAllPatterns() method from RewriteFiler to make this work.)


      Of course this coupling between two different filters isn't that nice.
      Any other idea?
      Should I create a Jira issue?