This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
(assume that everything is correctly declared in web.xml)
The specification says: "Before the forward method of the RequestDispatcher interface returns, the response content must be sent and commited, and closed by the servlet container" - so if the output stream is flushed and closed in ForwardTargetServlet.java I should potentially get IllegalStateException. I tried this on Tomcat 5.0.28 and no exception was thrown, and of course as I expected there was "text 2" in browser. Did anyone of you manage to find any trace in the specs how such cases should be treated by the container (or maby it's left for the vendors to choose whatever they want)??
PS. This question was influenced by some mock test question where the correct answer stated that IllegalStateException will be thrown [ February 12, 2005: Message edited by: Krzysiek Hycnar ]
The keyword is "flush". Writing to a stream does not always result is flushing the stream, because of implicit buffering mechanisms implemented by the Web Containers. What happens if you flushBuffer before forwarding your page?
Joined: Jan 02, 2004
This what happens if I flushBuffer prior forwarding is obvious. I get IllegalStateException - and that's it. The problem is not that I don't know what happens when I attempt to write something to stream that has already been flushed (because as I said the answer is IllegalStateException - finito).
The problem is what I what happens when control is returned to servlet that called RequestDipatcher.forward and then (after the control returned) tries to write something to the out stream (forward is just another method and if there were no ServletException, IOException or RuntimeException thrown in the forward target resource, control flow returns to the first instruction after RequestDipatcher.forward)?
The example I developed shows that in the browser you get "text 2" (which is fine - original buffer with "text 1" is cleared prior forwarding, then new message "text 2" is placed in it, and finally sent to the client), but there's no exeception caught by the container while attempting to execute the out.println("text 3"); line.
So my question is again: Is the container's behavior for "out.println("text 3");" like "afterforward" attempts unspecified in the Servlet 2.4 spec (I did't manage to find it, how about you?). in other words left to the vendors??
PS. At the moment it seems to me, that another copy of the out stream is created for the flush target resource, and the contents of its buffer are sent to the client's browser, whereas any actions on the original out stream after forward returns are somehow... ignored (at least in Tomcat)
Joined: Aug 25, 2003
Request dispatcher forward successfully handles your request. In your case writing "text 2" completes the web request. The control is NOT returned to the original servlet. Apologize for superficially reading your post.
Refer to Servlet 2.4 Specs, Pg 66, just above SRV .8.4.1.
In fact try setting some headers on your response object. It will have not effect either.
Joined: Jan 02, 2004
Unfortunately you're wrong. To prove that, please put a line like
somewhere below rd.forward(req, resp); and watch your logs. If you see "returns or not??" that means the control is back in the original servlet.
BTW. If you had read carefully what I'd posted, you wouldn't have asked me to read it again (I used exactly the words you want me to read in my original post )
This doesn't say anything about the control not returning to the original servlet (forward is a regular method it's invoked, executed and finally it returns), but only about what happens (should happen) to the output stream.