Christopher Schultz schrieb am 25.11.2008 um 09:31:17 (-0500):
> Michael Ludwig wrote:
> > Your argument in favour of the unified buffer sounds perfectly
> > logical to me. In the end, it's all bytes that get written,
> > regardless of whether or not I wrap a PrintWriter around the buffer.
> 
> There's always the case that some output has been written before your
> filter has been called. In that case, you have to make sure that your
> output goes to the correct place.

It's not at my discretion to decide where my output should go. Filter or
servlet, I try calling getWriter() or getOutputStream(), and if it that
throws an exception, I call the other. I am unaware of whether what I'm
writing to is the real thing or just a fake an upstream filter has
supplanted. I'm only responsible for things happening downstream. Sort
of like in real life.

Is this thinking flawed?

> That may mean turning your Writer contents into an OutputStream, or
> vice-versa. I think it's simpler to wrap whichever object the caller
> is actually requesting.

But can it be simpler than this:

package milu;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HttpResponseCatcher extends HttpServletResponseWrapper {
 private OutputStream buffer;
 private CapturedServletOutputStream stream;
 private PrintWriter writer;

 public HttpResponseCatcher( HttpServletResponse res) {
  super( res);
  this.buffer = new ByteArrayOutputStream();
  this.stream = new CapturedServletOutputStream( this.buffer);
  this.writer = new PrintWriter( new OutputStreamWriter( this.stream));
 }

 public ServletOutputStream getOutputStream() throws IOException {
  getResponse().getOutputStream();
  return stream;
 }

 public PrintWriter getWriter() throws IOException {
  getResponse().getWriter();
  return writer;
 }

 public String getCapturedOutput() { return buffer.toString(); }
 public byte[] getByteArray() { return buffer.toString().getBytes(); }
 public char[] getCharArray() { return buffer.toString().toCharArray(); }
}

> > I agree: You never know. And who knows what stuff gets set or
> > tweaked in Tomcat's internals for each one of getWriter() and
> > getOutputStream(). On the other hand, I haven't found any statement
> > to the effect that you have to pass through the calls to the
> > underlying response object.
> 
> No, you don't have to do this, but the benefit of doing it is that you
> have the wrapped request enforcing the "call either getWriter or
> getInputStream" requirement.

Looks like, yes, I *have* to call getWriter() and getOutputStream() on
the underlying object (and so, ultimately, on the real object, at the
end of the chain), in order to get *correct* behaviour in all scenarios,
including the one discussed here:

* static HTML file served by Tomcat's DefaulServlet
* no flush() prior to include()
* PrintWriter used, not ServletOutputStream

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