tags:

views:

623

answers:

3

The JavaEE API comes with the HttpServletResponseWrapper which, to quote the javadoc, "provides a convenient implementation of the HttpServletResponse interface that can be subclassed by developers wishing to adapt the response from a Servlet." Without subclassing, this class just passes all calls through to the wrapped response object. There's a similar wrapper for requests.

Can anyone point me at any utility libraries that provide useful subclass implementations of these classes? Particularly, I'm looking for a subclass of the response wrapper that captures the written response (as a String, byte[], whatever's appropriate) and exposes it via an API method.

I've written a rather half-baked version myself, but frankly, I shouldn't have to, and I'd rather throw it away and use one off the shelf.

A: 

good question, I wrote several subclasses of Http*ResponseWrapper such as:

dfa
A: 

In the past I've used the objects provide in the spring framework. In particular, this should work: http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/mock/web/MockHttpServletRequest.html

sillydino
Yeah, I tried that, but MockHttpServletResponse doesn't extend HttpServletResponseWrapper, and is no use for this task.
skaffman
+1  A: 

I am not aware of any implementation, even though the gzip example can be adapted easily by just writing to a ByteArrayOutputStream. You can also take ideas by looking at other response wrapper implementations at:

Original answer:

There is the classic article in JavaWorld Filter code with Servlet 2.3 model. You can find examples for wrapped request and response:

  • Compression the response

    public class CompressionResponseWrapper extends HttpServletResponseWrapper {
      protected ServletOutputStream stream = null;
      protected PrintWriter writer = null;
      protected int threshold = 0;
      protected HttpServletResponse origResponse = null;
      public CompressionResponseWrapper(HttpServletResponse response) {
    super(response);
    origResponse = response;
      }
      public void setCompressionThreshold(int threshold) {
    this.threshold = threshold;
      }
      public ServletOutputStream createOutputStream() throws IOException {
    return (new CompressionResponseStream(origResponse));
      }
      public ServletOutputStream getOutputStream() throws IOException {
    if (writer != null) {
      throw new IllegalStateException("getWriter() has already been " +
                                      "called for this response");
    }
    if (stream == null) {
      stream = createOutputStream();
    }
    ((CompressionResponseStream) stream).setCommit(true);
    ((CompressionResponseStream) stream).setBuffer(threshold);
    return stream;
      }
      public PrintWriter getWriter() throws IOException {
    if (writer != null) {
      return writer;
    }
    if (stream != null) {
      throw new IllegalStateException("getOutputStream() has already " +
                                      "been called for this response");
    }
    stream = createOutputStream();
    ((CompressionResponseStream) stream).setCommit(true);
    ((CompressionResponseStream) stream).setBuffer(threshold);
    writer = new PrintWriter(stream);
    return writer;
      }
    }
    
  • Handling file upload

    public class MultipartWrapper extends HttpServletRequestWrapper {
      MultipartRequest mreq = null;
      public MultipartWrapper(HttpServletRequest req, String dir)
                                     throws IOException {
    super(req);
    mreq = new MultipartRequest(req, dir);
      }
      // Methods to replace HSR methods
      public Enumeration getParameterNames() {
    return mreq.getParameterNames();
      }
      public String getParameter(String name) {
    return mreq.getParameter(name);
      }
      public String[] getParameterValues(String name) {
    return mreq.getParameterValues(name);
      }
      public Map getParameterMap() {
    Map map = new HashMap();
    Enumeration enum = getParameterNames();
    while (enum.hasMoreElements()) {
      String name = (String) enum.nextElement();
      map.put(name, mreq.getParameterValues(name));
    }
    return map;
      }
      // Methods only in MultipartRequest
      public Enumeration getFileNames() {
    return mreq.getFileNames();
      }
      public String getFilesystemName(String name) {
    return mreq.getFilesystemName(name);
      }
      public String getContentType(String name) {
    return mreq.getContentType(name);
      }
      public File getFile(String name) {
    return mreq.getFile(name);
      }
    }
    

The code is a bit old (june 2001!), but it demonstrate the usage well.

David Rabinowitz
I've edited the answer.
David Rabinowitz
Oh right, that's a bit more interesting, thanks for the clarification. I already have an implementation that caters for my immediate needs, I was just bemoaning the lack of a utility library that did it for me.
skaffman