Muhammad Kholid B
Muhammad Kholid B

Reputation: 477

JSF sendRedirect() java.lang.IllegalStateException: Committed

I am creating a web page that get an id from a previous page using getSessionMap() in FacesUtils. If the page did not get the id, it should be redirected to other page, in this case draft.jsf. Here is the code:

if ((FacesUtils.getSessionMap().get("id") == null)) {
    try {
        FacesUtils.getResponse().sendRedirect("draft.jsf");
        return;         
    } catch (Exception e) {
        e.printStackTrace();
}
} else {
    id = Long.valueOf(String.valueOf(FacesUtils.getSessionMap().get("id")));
}

But I always get java.lang.IllegalStateException: Committed when the id was null, and the page was not redirected to draft.jsf. What is wrong with my code? Any help would be really appreciated.

Here is the stacktrace:

java.lang.IllegalStateException: Committed
at org.mortbay.jetty.Response.resetBuffer(Response.java:1023)
at org.mortbay.jetty.Response.sendRedirect(Response.java:428)
at org.jleaf.erp.inv.controller.EditAssemblyController.init(EditAssemblyController.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:340)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:293)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:130)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:393)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1415)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:518)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:331)
at org.jlego.web.jsf.ViewScope.get(ViewScope.java:20)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:327)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
at org.jlego.baseweb.PieceletELResolver.getValue(PieceletELResolver.java:65)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:99)
at com.sun.el.parser.AstValue.getValue(AstValue.java:158)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:169)
at org.primefaces.util.ComponentUtils.getValueToRender(ComponentUtils.java:69)
at org.primefaces.component.inputtext.InputTextRenderer.encodeMarkup(InputTextRenderer.java:79)
at org.primefaces.component.inputtext.InputTextRenderer.encodeEnd(InputTextRenderer.java:50)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:312)
at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:55)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.panel.PanelRenderer.encodeContent(PanelRenderer.java:191)
at org.primefaces.component.panel.PanelRenderer.encodeMarkup(PanelRenderer.java:114)
at org.primefaces.component.panel.PanelRenderer.encodeEnd(PanelRenderer.java:55)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1764)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:401)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1221)
at org.jlego.web.WebLoginSessionFilter.doFilter(WebLoginSessionFilter.java:95)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:928)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

Upvotes: 2

Views: 10286

Answers (2)

BalusC
BalusC

Reputation: 1108567

It's likely because you're redirecting by plain servlet HttpServletResponse#sendRedirect() instead of JSF own ExternalContext#redirect() which is implicitly performing a FacesContext#responseComplete() call afterwards which instructs JSF to not perform the render response which would fill the HTTP response with the output of the target view.

E.g.

public void someMethod() throws IOException {
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    Long id = (Long) ec.getSessionMap().get("id");

    if (id == null) {
        ec.redirect("draft.jsf");
        return;
    }

    // ... ?
}

(note that I simplified some clumsiness (massaging long<-->string) and carelessness (swallowing exception) in your code as well; using @ManagedProperty("#{id}") to inject the property is after all probably yet easier)

Whenever you import something from javax.servlet inside a JSF artifact, you should stop developing and look around in ExternalContext class and think twice if you're really doing things the right way. Further, JSF utility library OmniFaces has a handy Faces utility class, removing the need to reinvent the FacesUtils wheel.


Update: Given the stack trace, another probable cause is that you're attempting to send a redirect in midst of rendering the response. It's not possible to take the already sent bytes of the rendered response back from the client in order to change the response. You should be performing the redirect job before the first byte of the response is ever sent to the client. E.g. in a pre render view listener method instead of bean's (post)constructor or even getter method.

<f:event type="preRenderView" listener="#{bean.someMethod}" />

Upvotes: 15

jsurls
jsurls

Reputation: 375

I ran into this problem before where somewhere else in my code there was a redirect being sent within the same request.

Double check that you don't have any filters trying to do a redirect as well.

Upvotes: 0

Related Questions