forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward.
What i don't understand is why having the next excerpt of code:
i don't get an IllegalStateException. I get printed all till "true" from response.isCommited(). After that i was waiting for an exception, but nothing happened.
P.S. I tested it on tomcat 6 container.
Inside the RequestDispatcher implementation class we get here when we forward:
So, if response.isCommitted() is true, than throw the exception.
Let's go farther. How is response.isCommitted() implemented:
That's the implementation from a response facade implementation that delegates the decision to a contained reponse.
Let's see what does it do:
Here we go. If any of those conditions are true, than the exception has to be thrown.
So why it is not thrown, if the flushBuffer method sets the appCommited to true.
The exception is really thrown, but it goes up till it gets here:
As it is described in the javadoc comment, it gets swallowed.
Why? Because at this moment it sets the status of the response as internat server error, but response has already been committed, so this has no effect at all.
When we forward to another component after the response has already been committed, next things happend:
- We get an exception logged into the container's log file.
- We get in the output everything that was flushed before the exception has been thrown.
- We don't get a visible error as response.
P.S. That also means that tomcat implementation deviates a little bit from the specification. Doesn't it?