Differences between ServletResponse and HttpServletResponseWrapper?
Asked Answered
P

2

16

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.

Prevent answered 11/8, 2011 at 9:5 Comment(2)
This code looks weird. The purpose of wrapping servlet response is to pass it further (chain.doFilter(request, resWrapper);) and intercept selected calls in the wrapper. This way you can, for instance, return different response writer that changes or compresses the content on the fly and sends it to the target response. This example doesn't have much sense... Could you provide the source of this (page, book?)Solstice
I found myself weird too. This code I took from a powerpoint slide of a University lecturer. It makes more sense if we do chain.doFilter(request, resWrapper); as your suggestionPrevent
B
26

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.

Barbarous answered 12/8, 2011 at 23:15 Comment(1)
But the original question is still unanswered, i.e. why can't we do all this with the original HttpServletResponse object itself?Marismarisa
S
13

That's a bad example which does not show the real benefit of request/response wrapper. Emitting HTML should be done by a JSP not by a Filter and for sure not by a Servlet. Go through our filters wiki page to get some ideas about what a Filter is to be used for.

A response wrapper is useful if you want to modify the response's behaviour or just want to collect information about the response while it is been used in the request-response chain. The modified behaviour takes then place whenever some servlet or JSP calls a certain method on the response. If you have overriden it in your wrapper class, then this one will be called instead. You could alter the behaviour or collect information there.

Here on Stackoverflow you can find real world examples of HttpServletResponseWrapper implementations by searching on code:"extends HttpServletResponseWrapper".

Shattuck answered 12/8, 2011 at 22:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.