wood burning stoves 2.0*
The moose likes Servlets and the fly likes forward() , sendRedirect() Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "forward() , sendRedirect()" Watch "forward() , sendRedirect()" New topic
Author

forward() , sendRedirect()

Mathias Nilsson
Ranch Hand

Joined: Oct 13, 2003
Posts: 107

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


SCJP2 , MCP( 70-229 ) , Preparing For SCWDC
Celina Paul
Greenhorn

Joined: Nov 01, 2003
Posts: 16
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.
Mike Curwen
Ranch Hand

Joined: Feb 20, 2001
Posts: 3695

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."
Malli Raman
Ranch Hand

Joined: Nov 07, 2001
Posts: 312
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.
Chandra Bairi
Ranch Hand

Joined: Sep 12, 2003
Posts: 152
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.


Thanks,
Shekar
Brusk Baran
Ranch Hand

Joined: Nov 15, 2001
Posts: 132
use out.clearBuffer() all the time, before you do any forwarding.
Mike Curwen
Ranch Hand

Joined: Feb 20, 2001
Posts: 3695

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.
Celina Paul
Greenhorn

Joined: Nov 01, 2003
Posts: 16
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.
Mathias Nilsson
Ranch Hand

Joined: Oct 13, 2003
Posts: 107
Thanks Mike and Celina for the explination of this.
Malli Raman
Ranch Hand

Joined: Nov 07, 2001
Posts: 312
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.

Thanks Celina.
- M.S.Raman
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: forward() , sendRedirect()