This is in Tomcat 6.0.18 on Java 1.6.

A servlet S includes an HTML fragment via RequestDispatcher.include()
while being wrapped by a filter F and being passed a wrapped response
WR.

Servlet S generates header and footer using the PrintWriter.

The HTML fragment, being a static resource, is served by the Tomcat's
DefaultServlet.

The response wrapper used by the filter overrides getWriter(), but not
getOutputStream(), because I don't know how to do it.

So the output of S gets collected by WR and is now available to F. And F
calls getWriter() on the original response, and this to my surprise
triggers an IllegalStateException:

  getOutputStream() has already been called for this response

But I haven't called getOutputStream() - I've called getWriter(). The
reason this happens seems to be that the HTML snippet served by the
DefaultServlet gets output using a ServletOutputStream, not a
PrintWriter. I checked the source code, and indeed:

  // Trying to retrieve the servlet output stream
  try { 
      ostream = response.getOutputStream();
  } catch (IllegalStateException e) {
      // If it fails, we try to get a Writer instead if we're
      // trying to serve a text file
      if ( (contentType == null)
              || (contentType.startsWith("text"))
              || (contentType.endsWith("xml")) ) {
          writer = response.getWriter();
      } else {
          throw e;
      }
  }

http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java

So is it the recommended approach in this sort of scenario (or contrived
example) to proceed as observed in the DefaultServlet, by first trying
one of SOS and PW, catch the exception and then try the other one?

Consider how the filter affects the processing here.

When F with WR is used, the call to response.getWriter() in S is
intercepted, the text is written to a buffer, and the DefaultServlet
does the include using an SOS.

When no such filter is used, S calls the real response.getWriter(),
and the include ends up being done using a PW after a caught
IllegalStateException in the DefaultServlet.

The problem arises when a filter is used that passes a response wrapper
containing a buffer on to servlet S. S writes to the buffer, and the
DefaultServlet writes to the real SOS.

So how can I implement getOutputStream() to substitute a buffer? Does
anyone have an implementation?

But even with my Filter overriding both getOutputStream() and
getWriter() and substituting buffers that will be written to, there is a
problem. Servlet S will write to one buffer, and the DefaultServlet will
write to another one. The place of the include set in the source code of
S will be lost. Is this analysis correct?

Michael Ludwig

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to