Wednesday, 26 June 2013

IllegalStateException in Response.SendRedirect

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.IllegalStateException
 org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:436)TestFilter.doFilter(TestFilter.java:42)



ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/webtest].[jsp]] (http--127.0.0.1-8080-1) Servlet.service() for servlet jsp threw exception: java.lang.IllegalStateException
        at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:436) [jbossweb-7.0.13.Final.jar:]
        at TestFilter.doFilter(TestFilter.java:42)      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
        at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
        at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_17]





This Exception occurs when you try to send response again when the response is already committed and flushed to user.The above exception stack trace is from JBoss AS 7.1.1.Final . For example , consider this sample code of a filter :
/**
  * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
  */
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  
 
 
  request.getRequestDispatcher("index.jsp").forward(request, response);
  ((HttpServletResponse)response).sendRedirect("new.jsp");
  chain.doFilter(request, response);
 }
Here in this code ,first the request will be forwarded to index.jsp and response will be flushed to user , then the control will again come back to filter and try to send another response (redirect)to user , and it will fail.

Usually we check multiple conditions in filter and accordingly forward and redirect , if two conditions are met , then it will create a problem .

To avoid this , you should have a return statement , or avoid redirecting or forwarding request , or these kind of things should be done by the last filter in the filter chain.

The apache Tomcat 7.x gives a more detailed description in error stack trace like this :


HTTP Status 500 - Cannot call sendRedirect() after the response has been committed

type Exception report

message Cannot call sendRedirect() after the response has been committed

description The server encountered an internal error 
(Cannot call sendRedirect() after the response has been committed) that prevented it from fulfilling this request.

exception

java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
 org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:483)
 TestFilter.doFilter(TestFilter.java:42)
Post comments and suggestions !!!