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();
+ }
}
}