1) The forward method must be called before the response is committed since it forwards the current request to the next resource for processing. If the response has already been commited the request is no longer valid and an Illegal State Exception is thrown.
When using the forward method of the RequestDispatcher or the response.sendRedirect( URL ) an IllegalStateException is thrown if the response is not commited. When is the response commited exactly? // Mathias
If your response output stream is not buffered..then any out.println() called before the forward would give you the Illegal State Exception. Because in this case, whatever you are printing in the output stream is directly getting forced out to the client. If the reponse output stream is buffered and the data added to the stream has not overflown the buffer size, then the buffer would be cleared and the forward() call would work. Also, flushBuffer() forces the data to the client and hence should not be called before forward() You can use the API isCommitted() on the ServletResponse object to make sure if any data has been committed to the client or not before calling the forward() method.
or better, design the flow of your program in such a way that you don't need to worry about whether or not the response has been committed.
Also, this sentence in your post is incorrect: When using the forward method of the RequestDispatcher or the response.sendRedirect( URL ) an IllegalStateException is thrown if the response is not commited.
* it should read "... if the response is commited."
Hi Celina, I am not sure about what you said. In my servlet i have used out.println("inside the servlet before forwarding"); before the forward method in the first servlet and it is printing properly. So how and when will it throw illegalStateException. I am not sure about the buffer concept. Can you please explain. Thanks & Regards, M.S.Raman.
Hello celina, kindly let me know if i have understood your answer properly. If we have buffered the response or if the response has not been flushed to the client then the forward works but if the response has been forwarded to the client then the forward will throw an IllegalStateException. is that correct and what does buffering meas in jsps. how can we add and extract the data from the buffer ie. write the data from the buffer to the client.
out.clearBuffer() is useless, if the buffer has been flushed once already.
The bottom line on IllegalStateException should be: if the buffer has been flushed at least once, the response is committed.
when a servlet or JSP produces output, it does so by writing to the output buffer. This buffer does *not* send any response back to the browser until it is full. Once it has flushed, the response is 'committed'. Why? Because once that first flush has been sent, the HTTP headers have been sent. HTTP headers cannot be sent more than once, as they occur in a different section of the HTTP response than the HTML body of the page.
What's the big deal with headers? When you attempt a server-side forward or a sendRedirect(), the resource you are forwarding to will try to set its own headers. These headers will occur "too late" in the overall total response sent back to the browser. By the time the buffer has flushed, the response is already on to the HTML portion of the response, and HTTP headers will not be understood or expected. This is why forwarding after a response has committed is disallowed. The sendRedirect() is disallowed for a similar reason. The redirect is actually *accomplished* through the use of HTTP headers. Again, if the buffer has already been flushed, it is *too late* to send these headers.
Joined: Nov 01, 2003
Hi Mali, Mike has explained the process in good detail. The default buffer size is 8k and buffering is on by default. To answer your question, the out.println() statement that you added before forward() was not enough to overflow the buffer and hence nothing was flushed out/committed to the client. And hence forward() worked without exceptions. If you add data which exceeds 8k, it would cause the response to be flushed out and then your forward() call would definitely throw an exception.
Joined: Oct 13, 2003
Thanks Mike and Celina for the explination of this.
Joined: Nov 07, 2001
Originally posted by Celina Paul: Hi Mali, Mike has explained the process in good detail. The default buffer size is 8k and buffering is on by default. To answer your question, the out.println() statement that you added before forward() was not enough to overflow the buffer and hence nothing was flushed out/committed to the client. And hence forward() worked without exceptions. If you add data which exceeds 8k, it would cause the response to be flushed out and then your forward() call would definitely throw an exception.