I have a logout link which looks like:
<h:form>
<div>
<h:commandButton value="Logout" action="#{Bean.logOut}" />
</div>
</h:form>
And the corresponding logout method:
public String logOut()throws Exception{
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpSession httpSession = (HttpSession)facesContext.getExternalContext().getSession(false);
httpSession.invalidate();
return "pretty:index?faces-redirect=true";
}
when i click on logout button it's working fine but seams when i'm trying to forward login page it's doesn't working and i got error like
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:483)
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138)
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138)
at com.test.Bean.onErrorHome(Bean.java:262)
at com.test.Bean.<init>(Bean.java:51)
at com.test.service.BeanList.<init>(BeanList.java:84)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at java.lang.Class.newInstance0(Class.java:374)
at java.lang.Class.newInstance(Class.java:327)
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:188)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:72)
at org.apache.el.parser.AstValue.getTarget(AstValue.java:94)
at org.apache.el.parser.AstValue.getType(AstValue.java:82)
at org.apache.el.ValueExpressionImpl.getType(ValueExpressionImpl.java:176)
at com.ocpsoft.pretty.faces.util.FacesElUtils.getExpectedType(FacesElUtils.java:50)
at com.ocpsoft.pretty.faces.beans.ParameterInjector.injectQueryParams(ParameterInjector.java:125)
at com.ocpsoft.pretty.faces.beans.ParameterInjector.injectParameters(ParameterInjector.java:55)
at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.afterPhase(PrettyPhaseListener.java:102)
at com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:189)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:107)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:145)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:690)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:477)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:137)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
How can i solving this problem . Please help me . Thanks in advance .
Look at the stack trace who's calling the sendRedirect
at the wrong moment:
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138)
at com.test.Bean.onErrorHome(Bean.java:262)
at com.test.Bean.<init>(Bean.java:51)
at com.test.service.BeanList.<init>(BeanList.java:84)
The page which you're redirecting to after logout is apparently referencing BeanList
in whose constructor another Bean
instance is manually been constructed in whose constructor onErrorHome()
method is been invoked which is calling HttpServletResponse#sendRedirect()
.
I'm not sure what you're all doing there, but given this problem it's definitely not done right. You're basically attempting to redirect while the page is busy generating HTML output. A part of that HTML has already been sent to the webbrowser (i.e. the response is already committed).
You've 2 options:
Move that logic to a servlet filter.
Perform the onErrorHome()
job during preRenderView
event instead of in constructor.
<f:event type="preRenderView" listener="#{beanList.init}" />
This method is invoked before JSF starts rendering/generating/sending HTML output, so you've all freedom to change the response to a different destination without risking IllegalStateException: response already committed
errors.