Should I Close the Servlet Outputstream

Should I close the servlet outputstream?

You indeed don't need to do so.

Thumb rule: if you didn't create/open it yourself using new SomeOutputStream(), then you don't need to close it yourself. If it was for example a new FileOutputStream("c:/foo.txt"), then you obviously need to close it yourself.

Reasons that some people still do it are just to ensure that nothing more will be written to the response body. If it would ever happen, then this will cause an IllegalStateException in the appserver logs, but this wouldn't affect the client, so the client still gets the proper response. This is also an easier debug to spot the potential problems in the request-response chain which you wouldn't see at first glance. For example, something else is appending more data to the response body somewhere further down in the chain.

Another reason which you see among starters is that they just wanted to prevent that more data is written to the response body. You see this often when JSP incorrectly plays a role in the response. They just ignore the IllegalStateExceptions in the logs. Needless to say that this particular purpose is bad.

Should one call .close() on HttpServletResponse.getOutputStream()/.getWriter()?

Normally you should not close the stream. The servlet container will automatically close the stream after the servlet is finished running as part of the servlet request life-cycle.

For instance, if you closed the stream it would not be available if you implemented a Filter.

Having said all that, if you do close it nothing bad will happen as long as you don't try to use it again.

EDIT: another filter link

EDIT2: adrian.tarau is correct in that if you want to alter the response after the servlet has done its thing you should create a wrapper extending HttpServletResponseWrapper and buffer the output. This is to keep the output from going directly to the client but also allows you to protect if the servlet closes the stream, as per this excerpt (emphasis mine):

A filter that modifies a response must
usually capture the response before it
is returned to the client. The way to
do this is to pass the servlet that
generates the response a stand-in
stream. The stand-in stream prevents
the servlet from closing the original
response stream when it completes and
allows the filter to modify the
servlet's response.

Article

One can infer from that official Sun article that closing the OutputStream from a servlet is something that is a normal occurrence, but is not mandatory.

Do I need to flush the servlet outputstream?

You don't need to. The servletcontainer will flush and close it for you. The close by the way already implicitly calls flush.

See also chapter 5.6 of Servlet 3.1 specification:

5.6 Closure of Response Object


When a response is closed, the container must immediately flush all remaining
content in the response buffer to the client. The following events indicate that the servlet has satisfied the request and that the response object is to be closed:

  • The termination of the service method of the servlet.
  • The amount of content specified in the setContentLength or
    setContentLengthLong method of the response has been greater than zero and
    has been written to the response.
  • The sendError method is called.
  • The sendRedirect method is called.
  • The complete method on AsyncContext is called.

Calling flush while still running the servlet's service is usually only beneficial when you have multiple writers on the same stream and you want to switch of the writer (e.g. file with mixed binary/character data), or when you want to keep the stream pointer open for an uncertain time (e.g. a logfile).

Close Encapsulating Writers/Streams for ServletOutputStream

The OutputStream is something you're not creating, you just query a reference to it with ServletResponse.getOutputStream(). Therefore if you put something around it (e.g. OutputStreamWriter or ZipOutputStream) the wrapper stream or writer will just write to it.

It is implementation dependant whether closing a wrapper stream or writer closes the underlying stream, so you should not close that. But since in most of the cases the wrappers only use the underlying stream to write bytes, it is more than enough to flush the wrapper.

In cases where the wrapper needs some finalizing, it should be (and generally is) the wrapper's responsibility to provide this finalizing functionality in a separate method. For example ZipOutputStream provides a finish() method which finishes writing the contents of the ZIP output stream without closing the underlying stream.

Summarizing:

You should not close the wrapper, but check if it provides some finalizing method without closing the underlying stream, which you should obviously call.

IOUtils: is it required to close OutputStream?

IOUtils.copy(InputStream, OutputStream) must not close the OutputStream. You can use it for example to concatenate different InputStreams and in this case it would be a bad idea if it would close the provided Input- and/or OutputStream.

As a rule of thumb any method should close only those steams it opens.
See also Should I close the servlet outputstream?

What happens to a servlet request after you close the output stream?

Well no, I have put something like that in an application and its running for quite sometime now, only the output stream is closed, so you can't communicate with the user's current request anymore, but since the doGet did not exist so the servlet's object is not destroyed
until the thread timeout ends.

There will probably be no issues regarding the network bandwidth, because the deletion and the waiting only happens in memory, like a background task, the only thing that affects that network's bandwidth is the time taken to send a response and since you respond fast, and then finish your work later then its ok.

I would suggest however to use a destroy() method instead to delete the file.

Does a servlets PrintWriter out stream really need to be closed?

If it's not you that's opening the stream, you should not close it.

The stream is opened by the container so the responsibility for closing lies with it.



Related Topics



Leave a reply



Submit