This week's giveaway is in the EJB and other Java EE Technologies forum.
We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line!
See this thread for details.
The moose likes Web Component Certification (SCWCD/OCPJWCD) and the fly likes What is allowed after forward() ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Web Component Certification (SCWCD/OCPJWCD)
Bookmark "What is allowed after forward() ?" Watch "What is allowed after forward() ?" New topic
Author

What is allowed after forward() ?

Oliver Rensen
Ranch Hand

Joined: Jul 23, 2004
Posts: 109

Hello ranchers,

I am confused about what is allowed after calling the forward()-method:

RequestDispatcher rd =
request.getRequestDispatcher("/ServletB");
rd.forward(request, response);
// What is allowed here?

David Bridgewater writes:
"What you can't do in ServletA - after the forward call - is anything that might attemt to affect the response. Well, you can do it - and the lines of code will execute harmlessly, having no effect."

That means, I can write into the response (this would not lead to an IllegalStateException), but I cannot flush the response (this would lead to an IllegalStateException).

Charles Lyons writes:
if (condition) {
rd.forward(request, response);
return;
}
response.setHeader("myheader", "myvalue");

"If we'd omitted the explicit return statement from above, the subsequent header modification would be executed and an IllegalStateException would be thrown since the response is committed."

A few pages later Charles Lyons writes:
"When forward() is invoked, it clears the current buffer. (...) When this method returns, the response should be considered committed, we shouldn't ideally write any more content to the response stream, but it isn't illegal to do so."

What is definitely allowed within the forwarding Servlet after returning from the forward()-method and without throwing a RuntimeException:
- Writes into the response without flushing.
- Sets a response-header.
- Both of them.
- Nothing of them.

Regards
Oliver
Abhishek Pratap
Ranch Hand

Joined: Apr 14, 2006
Posts: 43
Even i m confused on the same issue. As Enthuware said that IllegalException is thrown because once you forward, the response is committed by the called src.

there are two concerns.
1)
//code in servlet to get request dispatcher and PrintWriter
rd.forward(req,res);
out.println("Test");

it will throw IllegalStateException

2)

//code in servlet to get request dispatcher and PrintWriter
rd.sendError("Some error");
out.println("Test");

it will ignore out.println("Test");

in both the case response is committed...

can anyone clarify??

Regards,
Abhishek.
Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
Thanks for picking up a copy of my book and I hope you're finding it useful in your studies!

The resolution to your query is actually a simple set of rules which are:

  • forward() must be invoked before the response has been committed or an IllegalStateException is thrown. As a side effect, invoking forward() clears the current output buffer so it contains no content when the page being forwarded to starts writing.
  • Once your page returns from the forward() invocation, the response will be committed and closed automatically by the container.
  • After a response has been committed, this only means the headers are set in stone and cannot be modified - you can still write content to the output buffer without any errors, however...
  • Since in this case the return from the forward() also closes the response automatically, writing content to the output buffer will have no effect (i.e. nothing will be written to the client), though it won't produce any errors either. Note I recall a "feature" in older versions of Tomcat which do not close the response properly after a forward(), so content written will still go to the client - but this is not compliant with the specifications.
  • You cannot set or modify headers in the response since it has been committed. Technically (according to the specs) this is supposed to have no effect except perhaps a warning message in any error logs you have running; however, in practise some older versions of both Tomcat and Websphere and possibly other containers throw IllegalStateException (another "feature" of those containers).

  • I hope that clears it up for you, and happy studying!
    [ October 25, 2007: Message edited by: Charles Lyons ]

    Charles Lyons (SCJP 1.4, April 2003; SCJP 5, Dec 2006; SCWCD 1.4b, April 2004)
    Author of OCEJWCD Study Companion for Oracle Exam 1Z0-899 (ISBN 0955160340 / Amazon Amazon UK )
    Jan van Mansum
    Ranch Hand

    Joined: Oct 19, 2007
    Posts: 74
    I just tried the following code in NetBeans 5.5.1 with bundled Tomcat 5.5.17:



    In the page only appears "In forwarded-to servlet" and in the log appears no IllegalStateException after the message "Provoking IllegalStateException here?"


    SCJP 1.4, SCWCD 1.4
    Tarun Yadav
    Ranch Hand

    Joined: Sep 20, 2007
    Posts: 134
    You won't see anything in the browser since the response has already been committed. However, if you were to wrap it in a try/catch block, I'm sure you'd see it there.
    Jan van Mansum
    Ranch Hand

    Joined: Oct 19, 2007
    Posts: 74
    I am logging messages to the server log (see code in previous post). I don't see any IllegalStateException in the server log, which I do if - for instance - I call forward() after flushing the response buffer.
    [ October 25, 2007: Message edited by: Jan van Mansum ]
    Charles Lyons
    Author
    Ranch Hand

    Joined: Mar 27, 2003
    Posts: 836
    I just tried the following code in NetBeans 5.5.1 with bundled Tomcat 5.5.17... In the page only appears "In forwarded-to servlet" and in the log appears no IllegalStateException after the message "Provoking IllegalStateException here?"
    So it is doing almost what I said: i.e. when modifying the headers it does nothing - they must have fixed that bug in your version of Tomcat, where IllegalStateException used to be thrown (this isn't logged either which is still compliant behaviour). On the point of the output content not being written, this does in fact agree with the specs which state "Before the forward method of the RequestDispatcher interface returns, the response content must be sent and committed, and closed by the servlet container". Hence the entire response is committed and closed so no more content sent to the buffer will go to the client - though it won't cause an exception either! I had to check that with the offical spec as it just isn't sensible to write anything after the forward, and certainly I never do... The exam will almost certainly never ask that sort of question.

    I have ammended the list I gave above to make the body content point clearer.
    Oliver Rensen
    Ranch Hand

    Joined: Jul 23, 2004
    Posts: 109

    Hello Charles,

    thanks a lot for your comprehensive answer. Now it's clear to me what I can do after forwarding without throwing an Exception.

    Yes, I am satisfied with your book and I enjoy the reading. The mock-exam-questions at the end of every chapter are excellent. These questions help me a lot to find gaps within my understanding of servlets.

    Regards
    Oliver
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: What is allowed after forward() ?
     
    Similar Threads
    IllegalStateException
    Doubts on buffers, committing response (with RequestDespatcher, sendError)
    servlet: No return method after rd.forward?
    resetBuffer() OR flushBuffer()
    How to send request data