Differences between ServletResponse and HttpServletResponseWrapper?

18,562

Solution 1

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.

Solution 2

That's really a stupid example which does not show the benefit of request/response wrapper. Actually, the whole filter example is poor. Emitting HTML should be done by a JSP or at highest a servlet (but also that is still poor). Go through our filters wiki page to get some ideas about what a filter can 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 some concrete examples of useful HttpServletResponseWrapper implementations.

Share:
18,562
ipkiss
Author by

ipkiss

Updated on June 03, 2022

Comments

  • ipkiss
    ipkiss almost 2 years

    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.