On Thu, 9 May 2002, Steve McCarthy wrote:

> >service() {
> >   w= new PrintWriter( response.getOutputStream  );
> >   w.println(...)
> >}
> >
> >If you don't flush, then you'll get no output.
> >
> >That's not because of the servlet spec - but because of the way 
> >PrintWriter works, it'll put your output in a buffer and that'll not be 
> >written to the output stream.
> >
> Please note that the example uses a PrintWriter, and not a 
> BufferedWriter.  Looking at the source of PrintWriter, all of the 
> println() methods write the data to the underlying OutputStream - 

Are you sure you are looking at the right source ? I'm pretty sure 
the PrintWriter is doing the buffering - most likely in the Char2Byte 
conversion.

I did a lot of work on this area and I'm pretty sure I'm right on this,
there is a 8k buffer for everything that converts ( at least in
all VMs I worked with ). Jad may help you locate it. 



> characters are not buffered Writer level.  If there is any buffering, it 
> occurs in the OutputStream provided by the container, and is therefore 
> available to the container.  

You can probably check this by putting yet another wrapper - 
 new PrintWriter ( new MyOutputStreamWrapper( res.getOutputStream()),
and in MyOSWrapper you insert println() before calling the real stream.

I can bet you won't get any data passed to the output stream. 



> It isn't any different than obtaining the OutputStream from the 
> container, writing bytes to it, and then not calling flush on the 
> OutputStream:
> 
> service(...) {
>     OutputStream os = response.getOutputStream();
>     byte arr[] = ".......".getBytes();
>     os.write(arr);
>    // no os.flush();
> }

It is different - again, there is a buffer. If you don't trust me try 
yourself or use a dissasembler ( the char->byte converters are in sun.io,
they don't have sources ).


> By the way, wrapping the  application-level PrintWriter around the 
> OutputStream was intended to show two things:
> 1.  Be a really simple example.
> 2.  Demonstrate an inconsistent behavior that was present in Tomcat 
> 4.0.1 where, by obtaining an OutputStream, you prevented 
> ErrorReportValve from obtaining a Writer, and thereby avoided having 
> your data trashed.  I think that behavior may have changed in 4.0.4 and 
> beyond.

I do agree  ErrorReportValve has a bug and shouldn't touch the 
response if 2xx status, but that's a different story.


> >If you use w=response.getWriter() than it should work without flush,
> >since the container does have access to the buffer ( in the first 
> >case the container has no way to access your writer )
> >
> >I agree that a 2xx response with empty content is perfectly valid
> >and shouldn't be modified, that's a bug.
> >
> What is your opinion about 3xx codes?

I think it would be good to not touch them - the user does have a way to 
generate 'nice' messages ( using <error-code> in web.xml ).

But I don't think the spec explicitely forbids us to change the body
on 3xx. I would make this configurable at least.

Costin


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to