background image

Programming Customized Requests and Responses

<< The doFilter() Method | HttpServletResponseWrappe Class >>
<< The doFilter() Method | HttpServletResponseWrappe Class >>

Programming Customized Requests and Responses

Programming Customized Requests and Responses
There are many ways for a filter to modify a request or response. For example, a filter can add an
attribute to the request or can insert data in the response. In the Duke's Bookstore example,
HitCounterFilter
inserts the value of the counter into the response.
A filter that modifies a response must usually capture the response before it is returned to the
client. To do this, you pass a stand-in stream to the servlet that generates the response. 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.
To pass this stand-in stream to the servlet, the filter creates a response wrapper that overrides
the getWriter or getOutputStream method to return this stand-in stream. The wrapper is
passed to the doFilter method of the filter chain. Wrapper methods default to calling through
to the wrapped request or response object. This approach follows the well-known Wrapper or
Decorator pattern described in Design Patterns, Elements of Reusable Object-Oriented Software,
by Erich Gamma et al. (Addison-Wesley, 1995). The following sections describe how the hit
counter filter described earlier and other types of filters use wrappers.
To override request methods, you wrap the request in an object that extends
ServletRequestWrapper
or
HttpServletRequestWrapper
. To override response methods, you
wrap the response in an object that extends
ServletResponseWrapper
or
HttpServletResponseWrapper
.
HitCounterFilter
wraps the response in a
tut-install/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/filters/CharResponseWra
The wrapped response is passed to the next object in the filter chain, which is
BookStoreServlet
. Then BookStoreServlet writes its response into the stream created by
CharResponseWrapper
. When chain.doFilter returns, HitCounterFilter retrieves the
servlet's response from PrintWriter and writes it to a buffer. The filter inserts the value of the
counter into the buffer, resets the content length header of the response, and then writes the
contents of the buffer to the response stream.
PrintWriter out = response.getWriter();
CharResponseWrapper wrapper = new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(request, wrapper);
CharArrayWriter caw = new CharArrayWriter();
caw.write(wrapper.toString().substring(0,
wrapper.toString().indexOf(
"</body>")-1));
caw.write(
"<p>\n<center>" +
messages.getString(
"Visitor") + "<font color='red'>" +
counter.getCounter() +
"</font></center>");
caw.write(
"\n</body></html>");
response.setContentLength(caw.toString().getBytes().length);
out.write(caw.toString());
Filtering Requests and Responses
Chapter 4 · Java Servlet Technology
117