10. Given the following code snippet, what output would you expect?
A. �Will you see the source?�
B. �Will you see the target?�
C. An IllegalStateException is thrown.
D. Nothing appears; the thread hangs.
E. Both �Will you see the source?� and �Will you see the target?�
I had answered C, but book stated that correct answer is B !!! WTF !!!
And below is written:
A forward(� )is used to forward responsibility to complete the
response to another servlet. If the calling servlet adds data to the response
buffer, the target servlet erases that information. Consequently, you
see the output from the target response stream only.
Now, let's guys clarify this question.
To be truly, if you compile this example in Tomcat 4.0 version, you will get �Will you see the target?� string in browser.
It is obvious, that you will get it because
Tomcat has it's internal buffer (by default 1024 bytes) and first string is less than 1024 bytes in length. (And we should not rely on the internal Tomcat implementation, although it is Sun licensed Servlet Engine, this feature - servlets output buffer size - is not mentioned in Specification).
You can see in the
that by default output buffer is 1024 byte and we can not made it less than this value:
If you will change the example that first servlet produced bigger than 1 kB output - you will get the correct result: java.lang.IllegalStateException
So, even, if authors tried this example in real Servlet environment and got option that is stated as a correct one, they (as well their technical reviewers) don't have basic understanding on this topic.
Let's read further. WIll inform you about results ...
[ October 12, 2002: Message edited by: Mikalai Zaikin ]
javax.servlet.HttpServletRequest (although there are many tools to avoid this: starting from Alt+F7 in FAR and finishing by 'greep' utility in Unix), but this is not the case I wrote.
After I read this question and answer, I thought for a while, who went mad: me or book's authors.
And decided to compile this example in Tomcat environment. Even looked in Tomcat's sources to understand such "non-logical" behaviour. And found that it provides (as every well-written stream) default buffer, but this does not mean that we can write huge amount of output data to PrintWriter stream and then decide to forward another place.
Even more, I think that this explanation from authors can help to fail anybody during real exam.
So, I decided to open this thread.
ok, let's discuss.
1. Looking in Servlets specs:
SRV.8.4 The Forward Method
The forward method of the RequestDispatcher interface may be called by the
calling servlet only when no output has been committed to the client. If output data
exists in the response buffer that has not been committed, the content must be
cleared before the target servlet’s service method is called. If the response has been
committed, an IllegalStateException must be thrown.
2. Now, please, say me where it is said about default buffer size for servlet output? Yes, in the API there are mothods for defining and obtaining buffer size for response, but in example above they are not used.
AFAIR, there is default buffer only for JSP, which mentioned in JSP Specs.
3. Then, say me, from where do you know what servlet engine should we use for testing ? AFAIK, there are a lot of Servlet Engine (Jetty, Tomcat, WebLogic, WebSphere, etc..). If that example passed (by chance) on Tomcat, it can fail on another SE.
4. And finally, even if we took into account that we HAVE TO USE Tomcat (which licensed by SUN as reference implementation), do you know what defaild buffer size provide tomcat (and even provide it or not?). I wrote after looking into sources. Did you know that before? What will happen if it would be not 1024 bytes, but 256? Should the developer sit with calculator and count how much bytes he send to Writer to make sure can he forward, or no?
P.S. Can you use such approach in your development work? I hardly believe that.
P.P.S. The discussion was not about CONCRETE example (say again, it just passed by chance), but about approach. This approach is INCORRECT and DANGEROUS to implement. I think you will agree with me.
Originally posted by Barry Kushnir:
Agreed, this is not a great example, but it works. As long as the response was not committed in the example as per servlet spec, which it was not, it is working code.
But how could you determine, was response commited or no ?
You can not rely on chance (especially during exam).
This reminds me another situation.
When I have prepared to SCJP exam, there were questions about threads. Just example: first thread starts, second thread starts. Asked: in which order they will print their messages (threads are not synchronized). All the time I started class, threads printed messages in order they started (first, then second), but that DID NOT MEANT that it was correct answer. Even that I had run them 100 times (for example ;)) and they printed messages in order: first, second. According to specs we can not say for sure which thread will print it's message when they are not synchronized.
This is the same case: Eyes say one, but specification says another. What we should rely on: our eyes (weak argument for SUN) or SUN's specification (a little bit stronger argument for SUN).
Response buffering allows a servlet to write some amount of output with a guarantee that the response won't be immediatley committed. Responses may be committed by a buffer flush, or when the buffer fills. In the above example, it is clear that we do not have a buffer overrun, since there is no server on the market that sets a default buffer so small. And since we're not changing the default buffer size in the example, the example and answer is perfectly legitimate.
Originally posted by Barry Kushnir:
In the above example, it is clear that we do not have a buffer overrun, since there is no server on the market that sets a default buffer so small.
I can not agree with you that this will be perfect argument during exam in testing center. Nothing is clear. It's funny to sit and count how much I put to buffer, am I allowed to redirect or I'll get an exception.
May be you (like the book authors) have another opinion, but am just trying to follow specification.
Buffer in SE is used for reducing network load between server and client and not for such cases.