I've been digging around the web after fixing an issue this afternoon @ work where Cookies added to the HttpServletResponse weren't being properly reflected in the response headers because our Servlet had already retrieved the response's PrintWriter (i.e. response.getWriter()) before we added the cookies. I'm now aware that best practices dictate that response header modifications (i.e. setting content type, adding/editing Cookies, etc.) must be done prior to a call to getWriter() but, what I'm looking for is: Why?
We've been speculating about why retrieving the PrintWriter in effect freezes the response headers but why definitively does the Servlet specification enforce that?
getWriter. Returns a PrintWriter object that can send character text to the client. The PrintWriter uses the character encoding returned by getCharacterEncoding() .
setContentType. Sets the content type of the response being sent to the client, if the response has not been committed yet. The given content type may include a character encoding specification, for example, text/html;charset=UTF-8 .
All Known Implementing Classes: HttpServletResponseWrapper public abstract interface HttpServletResponse extends ServletResponse. Extends the ServletResponse interface to provide HTTP-specific functionality in sending a response. For example, it has methods to access HTTP headers and cookies.
The setContentType method sets the Content-Type header, and is used by the majority of servlets. The setContentLength method sets the Content-Length header, useful if the browser supports persistent (keep-alive) HTTP connections.
Section SRV.5.2 Headers of the Java™ Servlet Specification Version 2.4
To be successfully transmitted back to the client, headers must be set before the response is committed. Headers set after the response is committed will be ignored by the servlet container.
So the spec doesn't explicitly mention getWriter()
having an effect on setting headers.
However, your servlet container implementation may have chosen to treat the response as having been comitted once getWriter()
is called. That is subtly different.
In some of the containers I've worked with you get a warning logged when you attempt to set a header after the response has been comitted.
It is always worth calling getWriter()
as late as possible, as you may want the opportunity to set the character encoding, etc, which must be set before getWriter()
is called.
Because the headers precede the body in HTTP. That's why they're called 'headers'. If you call getWriter() you are writing to the body, so afterwards it is too late to start changing response header values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With