but When i tried the following code i didnt an illegalstateexception:
why is the exception not coming for the second code snippet? I interchanged the place to call the getWriter() and getOutputStream() methods.I thought the error should come in both the cases. [ November 02, 2008: Message edited by: Teena George ]
For first code block: Reason of getting IllegalStateException is, we can not start/get two OutputStream for single resource. For e.g: if you try to get Character stream of one file for which one byte stream is already in use, you will get an exception. The same thing is happening here: you've already occupied character stream of Response object and trying to get byte stream of same object (visualize this as, two different users available in same network are trying to write in shared excel sheet).
For second code block: This is really interesting, I've tried few different combination to get the clear picture but couldn't find out any particular reason. Here bytestream is already been flushed out and after that we're trying to get character stream, so technically there's no any problem for resource's state (as we are getting them one after another) but then it should print your "will it reach there?" line.
Will try to find exact reason for this. Thanks for nice question.
Joined: May 01, 2008
Thanks Nishit. waiting for you to come up with a reason for this odd behavior.
Calling flush() on the ServletOutputStream commits the response. Either this method or getWriter() may be called to write the body, not both.
Throws: IllegalStateException - if the getWriter method has been called on this response IOException - if an input or output exception occurred
The Javadoc of both the methods are similar except the type of stream being returned.
As such in the code snippet 1, you are obtaining both the character and binary streams one after another. That's the reason you get the IllegalStateException.
In the second scenario, You do obtain one output stream first and then you are flushing it. As per the JavaDoc of the flush() method, it does nothing!, except it flushes the stream by sending the pending unwritten characters to the stream from the buffer (if any). Obviously there is no point/reason to get an error. But the output should be present! That's quite surprising!
The actual output is "an error is thrown at both the cases!" But the location at which the error is thrown varies!
In code snippet1, the error is thrown (flushed) into the output stream why because you first obtained an output stream and then you try to get the binary stream. As the output stream is already available, the container writes the error into the output stream (which you can see it in the browser) when you are trying to obtain the binary stream later.
Whereas in the second snippet, you first obtain a binary stream. Then when you try to get the output stream, the container can't write it into the binary stream. But it throws the output in the container's log file. You can closely look at the log file of your web server (container).
In both the cases, an IllegalStateException is thrown!!
See the logs of my execution below. I use Netbeans 6.0 with Apache 6.0.16.
for code snippet 1:
Nov 5, 2008 12:20:55 AM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet ObtainTwoOutputStreams threw exception java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.catalina.connector.Response.getWriter(Response.java:610) at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198) at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112) at j2ee.practices.servlet.forum.javaranch.f18.t014851.ObtainTwoOutputStreams.doGet2(ObtainTwoOutputStreams.java:112) at j2ee.practices.servlet.forum.javaranch.f18.t014851.ObtainTwoOutputStreams.processRequest(ObtainTwoOutputStreams.java:45) at j2ee.practices.servlet.forum.javaranch.f18.t014851.ObtainTwoOutputStreams.doGet(ObtainTwoOutputStreams.java:58) at javax.servlet.http.HttpServlet.service(HttpServlet.java:690) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
Note: You see this output in the Browser (output stream) as well!
For the snippet 2:
SEVERE: Servlet.service() for servlet ObtainTwoOutputStreams threw exception java.lang.IllegalStateException: getWriter() has already been called for this response at org.apache.catalina.connector.Response.getOutputStream(Response.java:579) at org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:183) at javax.servlet.ServletResponseWrapper.getOutputStream(ServletResponseWrapper.java:102) at j2ee.practices.servlet.forum.javaranch.f18.t014851.ObtainTwoOutputStreams.doGet1(ObtainTwoOutputStreams.java:85) at j2ee.practices.servlet.forum.javaranch.f18.t014851.ObtainTwoOutputStreams.processRequest(ObtainTwoOutputStreams.java:42) at j2ee.practices.servlet.forum.javaranch.f18.t014851.ObtainTwoOutputStreams.doGet(ObtainTwoOutputStreams.java:58) at javax.servlet.http.HttpServlet.service(HttpServlet.java:690) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
Note: This you do NOT see in browser as the error is thrown only when the OutputStream is obtained!
Hope this clarifies!
Good Post Teena [ November 04, 2008: Message edited by: Raghavan Muthu ]
I also had a similar thought of doing a full flushing of streams and to check with the container and its version. Well, beforehand i just simply tried executing (as with the JavaDoc API in mind) and I got one conclusion.
I believe it somehow gives the proper clarification. Isnt it?