I’ve recently encountered the following exception…
java.lang.IllegalStateException: Cannot obtain Writer because OutputStream is already in use
I understand the nature of the exception; namely the code can use a Writer or OutputStream but never both in the same request. How is code further down the stack supposed to handle the case where one already exists? OR is there a design/arch pattern that can avoid this problem in the first place?
Example; consider a 3rd party filter that decorates the output of a request and it gets an OutputStream. How is a filter or a servlet that needs to work with a Writer supposed to “know” that an OutputStream was already opened and should it care? The converse is also a valid Q.
I’ll attempt to address the more specific question raised in your example:
The Servlet API also disallows the use of both Writer and OutputStream when populating the response, as indicated in the API documentation for the ServletResponse.getWriter() method:
If a filter (third party or otherwise) wants to write to the response, especially after servlet(s) have generated it, it ought to assume that
close()method on the Writer or the OutputStream object.To account for this, the filter must create a HttpServletResponseWrapper instance, pass it downstream to the servlet for population, read it back in again, and then populate the actual container-managed HttpServletResponse object.
The above would also hold good if the filter were to populate the response first (before the request is processed further). It should perform the population on the actual HttpServletResponse object, pass a wrapper downstream, and then write the contents of the wrapper to the actual object.