users@glassfish.java.net

Re: servlet: try ... finally {out.close();} <-bad idea?

From: Witold Szczerba <pljosh.mail_at_gmail.com>
Date: Sun, 30 May 2010 17:04:08 +0200

2010/5/30 Hassan Schroeder <hassan.schroeder_at_gmail.com>:
> On Sun, May 30, 2010 at 5:06 AM, Witold Szczerba <pljosh.mail_at_gmail.com> wrote:
>
>> Hmmm... best practice is to never generate output from a servlet? What
>> else servlet actually can do?
>
> Process request input, interact with a database, do calculations, do
> basically anything in the Model or Controller part of MVC, and pass
> the appropriate values to the View.

OK, so how the "pass values to the view" part is supposed to be done?
Servlet has the "response" object and someone, sooner or later, will
have to write to it... So, going back to my original question: how
should it look like? Should the "out.close();" happen unconditionally
(finally block)?

Here is the background: I would like to create some simple, example
application, just to try something new. For last few years, I was
building applications like this: Swing over WebStart as front-end and
EJB container as back-end, remote session beans were facade for Swing
rich client.
Now I would like to test web browser/JavaScript as front-end, so I
need something else as a facade, remote session bean interfaces won't
work here. At first I was thinking about JAX-RS, but I it looks like
it's not ready yet:
https://jersey.dev.java.net/servlets/BrowseList?list=users&by=thread&from=2955660

So, I was trying my luck with one level lower: servlets. Security +
full Java EE integration works like a charm here, it seems like a good
facade for AJAX calls. But, as I just said: sooner or later - it will
happen and data will go into PrintWriter.


>> And what about the problem I mentioned, when after exception, the
>> servlet container generated OK HTTP Status?
>
> That's exactly the problem with directly writing output the way you're
> describing: once you start, you've *already committed the response*
> including the status (200 OK) header. If something blows up later in
> your code there's no way to "unwind" it -- the response headers are
> already on their way to the client. (You *could* buffer the response
> and flush when done, but that isn't perfect either, for other reasons.)
>
> OTOH, if you're using your servlet(s) to prepare the response values
> to pass to a view object and something goes wrong, you can forward
> to an appropriate error page, with an appropriate status header.


Hmm, you are right here... What if something bad happens after...
say... 100MB of data already written to PrintWriter... (hypothetical
situation). Nothing can go back in time and change the HTTP response
status. Unless, Glassfish buffers everything waiting for
PrintWriter#close before sending data to client... and this is
something I would not like.