Skip to main content

servlet: try ... finally {out.close();}

14 replies [Last post]
Anonymous

Hi there,
Today I was researching servlets. As far as I can see, this is very
common conception (for example NetBeans uses such templates)

response.setContentType("text/plain");
PrintWriter out = response.getWriter();
try {
...
out.print...
...
} finally {
out.close();
}

However, it looks like very bad idea to close PrintWriter in finally
block, it should be done like this:

response.setContentType("text/plain");
PrintWriter out = response.getWriter();
...
out.print...
...
out.close();

The problem with first approach is that when exception is thrown
inside try/finally block, server will send HTTP Status 200 (OK) status
with blank or partially generated page (response writer is closed
before exception has been propagated to servlet container).
In second approach, exception will prevent the "out.close();" to
happen and server will return HTTP Status 500 (internal server error),
not some partially generated page with OK status.

Does it sound good, or maybe this is a Glassfish bug?

Thanks,
Witold Szczerba

P.S.
GlassFish v3 (build 74.2)
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Server VM (build 16.3-b01, mixed mode)
Ubuntu 10.04 32bit

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Hassan Schroeder

On Sun, May 30, 2010 at 10:46 AM, Witold Szczerba
wrote:

> OK, JSP is for template-based response, and every container is
> supposed to handle it. How about something else like FreeMarker?

Never used it, but it appears to be similar to JSP, though a servlet
container wouldn't be required to implement support for it, since it's
not a standard. I'd guess adding support for it is pretty easy :-)

> Or
> anything non-template-based like JAXB or my own marshaller? The
> container is not going to help with that, request dispatcher is not
> going to forward to such a marshaller, is it?

Does JAXB or your marshaller implement the servlet spec? If not,
then no, or at least nothing good will happen :-)

The separation of concerns in the MVC pattern appeals to me. The
less low-level plumbing I have to deal with, the better. YMMV.

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
twitter: @hassan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Mark Mielke

I've been reading this thread in interest.

The general consensus seems to be "use a framework - do not try and use
the PrintWriter yourself."

However, I don't think this answers the question. It avoids the question
entirely.

There are times when using the PrintWriter yourself makes sense. Let's
treat the question of when to extend the Servlet interface and use the
PrintWriter directly as a separate question from what the correct way to
use the PrintWriter is when an exception is encountered.

JSP/JSF and Jersey were all mentioned. What do *they* do?

There is always the possibility of an exception being raised. The "try
... finally { out.close(); }" seems like a good idea, but if it isn't -
what is the alternative? What does JSP/JSF and/or Jersey do when they
implement the Servlet interface and they encounter an exception after
having written out the HTTP header, but before closing the connection?

Thanks,
mark

--
Mark Mielke

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Hassan Schroeder

On Sun, May 30, 2010 at 11:15 AM, Mark Mielke wrote:

> However, I don't think this answers the question. It avoids the question
> entirely.

I'd say it "reframes the issue", the *original* question being about serving
a page with a 200 OK header when there's actually been an error, and
there's an open PrintWriter instance.

> There are times when using the PrintWriter yourself makes sense.

I doubt it, but for the sake of discussion ... :-)

> There is always the possibility of an exception being raised. The "try ...
> finally { out.close(); }" seems like a good idea

Of course it is, or at least I can't imagine a reason to leave it open --
but it's *not* going to change the fact that the response has been
committed, and the error in your view code will be ugly and out of
sync with the response header.

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
twitter: @hassan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Hassan Schroeder

On Sun, May 30, 2010 at 9:42 AM, Witold Szczerba
wrote:

> I am sorry, but still, I  do not get it. You are saying my servlet is
> supposed to place appropriate values into the request or session and
> forward the request to the view. What does it mean the container is
> responsible for writing view to the response?

Just like the container is responsible for writing static pages -- HTML,
CSS, JavaScript -- to the response.

> According to what you say - it is wrong, as servlet should not write
> data to the response, the container should do it. So in this case, my
> servlet should place the "Customer" object into the request or session
> (an then what?). What does it mean? Could you give me some tiny
> example?

Servlet:

Customer customer = Customer.find(customerId);
request.setAttribute("customer", customer);
RequestDispatcher rd =
this.getServletContext().getRequestDispatcher(someViewPage);
rd.forward(request, response);

JSP (someViewPage):

Hello, ${customer.firstName}

That's HTML, but you can as easily format as XML, JSON, whatever.
The container is responsible for interpreting it and writing the response.

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
twitter: @hassan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Witold Szczerba

2010/5/30 Hassan Schroeder :
> Servlet:
>
> Customer customer = Customer.find(customerId);
> request.setAttribute("customer", customer);
> RequestDispatcher rd =
> this.getServletContext().getRequestDispatcher(someViewPage);
> rd.forward(request, response);
>
> JSP (someViewPage):
>
>

Hello, ${customer.firstName}

>
> That's HTML, but you can as easily format as XML, JSON, whatever.
> The container is responsible for interpreting it and writing the response.

OK, JSP is for template-based response, and every container is
supposed to handle it. How about something else like FreeMarker? Or
anything non-template-based like JAXB or my own marshaller? The
container is not going to help with that, request dispatcher is not
going to forward to such a marshaller, is it?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

emiddio-verizon

listening to this dialog -- and i still dont quite get it.

JSP is just a servlet -- its not a container; you can compile your jsp into
a servlet.

if the jsp servlet is writing output -- then whats the difference -- one
servlet vs another servlet???

gary

----- Original Message -----
From: "Witold Szczerba"
To:
Sent: Sunday, May 30, 2010 10:46 AM
Subject: Re: servlet: try ... finally {out.close();} <-bad idea?

> 2010/5/30 Hassan Schroeder :
>> Servlet:
>>
>> Customer customer = Customer.find(customerId);
>> request.setAttribute("customer", customer);
>> RequestDispatcher rd =
>> this.getServletContext().getRequestDispatcher(someViewPage);
>> rd.forward(request, response);
>>
>> JSP (someViewPage):
>>
>>

Hello, ${customer.firstName}

>>
>> That's HTML, but you can as easily format as XML, JSON, whatever.
>> The container is responsible for interpreting it and writing the
>> response.
>
> OK, JSP is for template-based response, and every container is
> supposed to handle it. How about something else like FreeMarker? Or
> anything non-template-based like JAXB or my own marshaller? The
> container is not going to help with that, request dispatcher is not
> going to forward to such a marshaller, is it?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Hassan Schroeder

Since no one else commented ... :-)

On Fri, May 28, 2010 at 7:22 AM, Witold Szczerba
wrote:

> Today I was researching servlets. As far as I can see, this is very
> common conception (for example NetBeans uses such templates)
>
>   response.setContentType("text/plain");
>   PrintWriter out = response.getWriter();

> Does it sound good, or maybe this is a Glassfish bug?

I'm not sure what this has to do specifically with Glassfish, but I'd
say current best practice is to never generate output (logging aside)
from a servlet; generate values to populate your view code (JSP/EL,
Velocity, whatever). Sticking to MVC makes your life easier in a lot
of ways. :-)

YMMV,
--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
twitter: @hassan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Witold Szczerba

2010/5/29 Hassan Schroeder :
> I'm not sure what this has to do specifically with Glassfish, but I'd
> say current best practice is to never generate output (logging aside)
> from a servlet;

Hmmm... best practice is to never generate output from a servlet? What
else servlet actually can do?
And what about the problem I mentioned, when after exception, the
servlet container generated OK HTTP Status?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Hassan Schroeder

On Sun, May 30, 2010 at 5:06 AM, Witold Szczerba
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.

> 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.

HTH,
--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
twitter: @hassan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Witold Szczerba

2010/5/30 Hassan Schroeder :
> On Sun, May 30, 2010 at 5:06 AM, Witold Szczerba
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&fro...

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.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Hassan Schroeder

On Sun, May 30, 2010 at 8:04 AM, Witold Szczerba
wrote:

> 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...

But not your servlet. Your servlet(s) simply perform whatever logic
they're intended to do and place the appropriate values into the
request (or session) and then forward the request to the view. The
container is responsible for writing that view to the response.

> So, going back to my original question: how
> should it look like? Should the "out.close();" happen unconditionally
> (finally block)?

It's irrelevant, you shouldn't be doing it, but theoretically, yes, of
course; why would you *not* want that PrintWriter closed??

> 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.

If you're doing it right, you'll never be calling a PrintWriter yourself. Not
ever :-)

--
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
twitter: @hassan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Witold Szczerba

2010/5/30 Hassan Schroeder :
> On Sun, May 30, 2010 at 8:04 AM, Witold Szczerba
wrote:
>
>> 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...
>
> But not your servlet. Your servlet(s) simply perform whatever logic
> they're intended to do and place the appropriate values into the
> request (or session) and then forward the request to the view. The
> container is responsible for writing that view to the response.
>
>> So, going back to my original question: how
>> should it look like? Should the "out.close();" happen unconditionally
>> (finally block)?
>
> It's irrelevant, you shouldn't be doing it, but theoretically, yes, of
> course; why would you *not* want that PrintWriter closed??
>
>> 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.
>
> If you're doing it right, you'll never be calling a PrintWriter yourself. Not
> ever :-)
>

I am sorry, but still, I do not get it. You are saying my servlet is
supposed to place appropriate values into the request or session and
forward the request to the view. What does it mean the container is
responsible for writing view to the response?

Tell me if there is something wrong in such a case:
1) servlet is invoked with some parameter, for example: customer ID,
2) servlet takes customerId from request and asks some bean to fetch data,
3) said bean returns some object, let's say it is a Customer object,
4) servlets asks some marshaller, e.g. JAXB to write Customer object
to the output - passing its PrintWriter as a "sink".

According to what you say - it is wrong, as servlet should not write
data to the response, the container should do it. So in this case, my
servlet should place the "Customer" object into the request or session
(an then what?). What does it mean? Could you give me some tiny
example?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Dominik Dorn

He probably has a JSP/JSF environment in mind.
There you'll gather your data (model) in the controller (servlet),
and then redirect to a certain view (a jsp page; View) which
then simply accesses the model and displays it.

While its the right way to do in general, I'm not sure if its
necessary in your case. You simply want to have a way to get some
json/xml data to
create your jquery pages right?

If so, you should really take another look at jersey.

--
Dominik Dorn
http://dominikdorn.com

Linkin Park Lyrics http://www.lyrix.eu/lyrics/Linkin-Park/ !

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Witold Szczerba

2010/5/30 Dominik Dorn :
> He probably has a JSP/JSF environment in mind.
> There you'll gather your data (model) in the controller (servlet),
> and then redirect to a certain view (a jsp page; View) which
> then simply accesses the model and displays it.
>
> While its the right way to do in general, I'm not sure if its
> necessary in your case. You simply want to have a way to get some
> json/xml data to
> create your jquery pages right?
>
> If so, you should really take another look at jersey.
>

I wrote in my previous mail:
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&fro...

There are no such issues with servlets, this is why I am interested in them.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net