I am new to servlet and reading some text about filters and wrappers. I can understand filters but got confused about wrappers. In the book, the author gives an example:
In case no wrapper:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
String name = request.getParameter("name").trim();
try {
chain.doFilter(request, response);
PrintWriter out = response.getWriter();
if (name.length() == 0) {
out.println("Some message");
out.println("</body>");
out.println("</html>");
out.close();
}
} catch (Throwable t) {
}
}
In case of wrapper:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
String name = request.getParameter("name").trim();
HttpServletResponse httpRes = (HttpServletResponse) response;
HttpServletResponseWrapper resWrapper = new HttpServletResponseWrapper(httpRes);
try {
chain.doFilter(request, response);
PrintWriter out = resWrapper.getWriter(); // why dont we just use response.getWriter();
if (name.length() == 0) {
out.println("<h3>Some message");
out.println("</body>");
out.println("</html>");
out.close();
}
} catch (Throwable t) {
}
}
Why we need HttpServletResponseWrapper
while we can do the same thing with ServletResponse
in case 1? Can anyone give me a clear example that we MUST use HttpServletResponseWrapper
instead of ServletResponse
? I have tried to google but found no luck.
BalusC's answer is good, but it might be a little overwhelming if you're just starting out.
Put simply: SerlvetResponse and its extension, HttpServletResponse, are interfaces telling you what methods are available to call to do the things you need. In the normal course of working with Filters, Servlets, et al., you'll use HttpServletResponse often to tell your app how to respond to requests.
HttpServletResponseWrapper is one particular implementation of HttpServletResponse which gives you a convenient way to wrap an existing response with some logic of your own without having to write a whole new implementation of the interface. It has a lot of methods, so this is really nice. As a trivial example, suppose you wanted to disallow calls to response.flushBuffer(). This code, using HttpServletResponseWrapper, will do that:
class DisallowFlushResponseWrapper extends HttpServletResponseWrapper {
public DisallowFlushResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public void flushBuffer() {
throw new UnsupportedOperationException("Don't call this!");
}
}
The typical way to use such a wrapper would be to create a filter like this:
class DisallowFlushFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) {
if (response instanceof HttpServletResponse) {
HttpServletResponse newResponse =
new DisallowFlushResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, newResponse);
}
...
}
...
}
Note that we wrap the response coming into the filter with an instance of our own wrapper. Then we hand the wrapper down to the next item in the filter chain. Thus anything that comes after this filter will get an exception if it calls flushBuffer() because it will be calling it on our wrapper. The wrapper, due to its default behavior, will delegate any other call to the wrapped response, which is the real one, so everything except calls to that one method will work normally.