JSF sendRedirect()java.lang.IllegalStateException:已提交

时间:2013-05-28 15:05:14

标签: jsf redirect illegalstateexception

我正在使用FacesUtils中的getSessionMap()创建一个从上一页获得 id 的网页。如果网页未获得 ID ,则应将其重定向到其他网页,在本例中为 draft.jsf 。这是代码:

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")));
}

但是当id null 时,我总是得到 java.lang.IllegalStateException:Committed ,并且页面未重定向到 draft.jsf 。我的代码出了什么问题?任何帮助都会非常感激。

这是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)

2 个答案:

答案 0 :(得分:14)

这可能是因为您通过普通的servlet HttpServletResponse#sendRedirect()而不是JSF自己的ExternalContext#redirect()进行重定向,后者隐含地执行FacesContext#responseComplete()调用,这指示JSF不执行渲染响应使用目标视图的输出填充HTTP响应。

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;
    }

    // ... ?
}

(注意我在你的代码中简化了一些笨拙(按摩长< - >字符串)和粗心(吞咽异常);使用@ManagedProperty("#{id}")注入属性毕竟可能还没有更容易)

每当你从JSF工件中的javax.servlet导入某些内容时,你应该停止开发并在ExternalContext类中环顾四周,如果你真的以正确的方式做事,请三思而后行。此外,JSF实用程序库OmniFaces有一个方便的Faces utility class,无需重新发明FacesUtils轮。


更新:鉴于堆栈跟踪,另一个可能的原因是您尝试在呈现响应期间发送重定向。为了更改响应,不可能从客户端返回已发送的响应的已发送字节。您应该在将响应的第一个字节发送到客户端之前执行重定向作业。例如。在预渲染视图监听器方法中,而不是bean的(post)构造函数或甚至是getter方法。

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

答案 1 :(得分:0)

我遇到了这个问题,之后在我的代码中的其他地方,在同一个请求中发送了重定向。

仔细检查您是否还有尝试重定向的过滤器。