Just realized I forgot to attach the diff.  Sorry, it was late =P

Rich

Richard Wallace wrote:

Hello,

I'm still having issues with the ExternalContext.redirect() method and I'm wondering if anyone has a workaround. The issue comes up when I'm trying to redirect a user to a page they requested before logging in. A simple externalContext.redirect() should work but I wind up with this exception.

java.lang.IllegalStateException
at org.apache.coyote.tomcat5.CoyoteResponseFacade.sendRedirect(CoyoteResponseFacade.java:352) at org.apache.myfaces.context.servlet.ServletExternalContextImpl.redirect(ServletExternalContextImpl.java:489) at org.apache.myfaces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:148) at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:85)
       at javax.faces.component.UICommand.broadcast(UICommand.java:106)
at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:87) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:161) at org.apache.myfaces.lifecycle.LifecycleImpl.invokeApplication(LifecycleImpl.java:270) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:86)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:94)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)

This means that in spite of the ExternalContext.redirect() method being called, which is supposed to call FacesContext.responseComplete(), the navigation rules are still being processed and trying to redirect the user for a second time in the same request. This causes Tomcat to throw the IllegalStateException.

After looking through the code for ExternalContext, it's clear that it's not calling FacesContext.responseComplete(). I tried adding that after my call to ExternalContext.redirect() and got the same result. So, it seems that the NavigationHandler is ignoring the FacesContext.responseComplete().

I've taken a closer look at the source and it seems that the problem could be solved by wrapping lines 83-88 in impl/src/java/org/apache/myfaces/application/ActionListenerImpl.java in an if statement that checks the FacesContext.getResponseComplete() return value. I've attached a diff that does just that. Hopefully this is acceptable cause this is something that I'd really like to mark as done on my todo list =P

Thanks,
Rich


Index: src/java/org/apache/myfaces/application/ActionListenerImpl.java
===================================================================
--- src/java/org/apache/myfaces/application/ActionListenerImpl.java     
(revision 232576)
+++ src/java/org/apache/myfaces/application/ActionListenerImpl.java     
(working copy)
@@ -80,12 +80,14 @@
             }
         }
 
-        NavigationHandler navigationHandler = 
application.getNavigationHandler();
-        navigationHandler.handleNavigation(facesContext,
-                                           fromAction,
-                                           outcome);
-               //Render Response if needed
-               facesContext.renderResponse();
-
+        if (facesContext.getResponseComplete()) 
+        {
+            NavigationHandler navigationHandler = 
application.getNavigationHandler();
+            navigationHandler.handleNavigation(facesContext,
+                                               fromAction,
+                                               outcome);
+            //Render Response if needed
+            facesContext.renderResponse();
+        }
     }
 }

Reply via email to