Custom Http Servlet Response Wrapper

One day, I had a requirement to change the response before it sent to the client. My application contains many servlet and jsp files so I needed some mechanism to change the response without updating each and every servlet and jsp. I found that this can be handled via custom http servlet response. In this post, I create sample wrapper and filter to give you a brief idea that how I have achieved this. In this sample wrapper, I convert response content to upper case but trust me, a lot can be done here.

Custom response wrapper class

Refer below sample response wrapper class which extends HttpServletResponseWrapper. It overrides getOutputStream() and getWriter()> methods of the super class. From getWriter() method I create PrintWriter object which wrap the instance variable stringWriter. I have declared stringWriter as an instance variable and I return the reference of the same so whatever is written by the servlet or jsp would be written to this stringWriter. Later we can examine/update the content of stringWriter.

package com.elitejavacoder.wrapper;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
*
* @author Atul Prajapati
*
*/
public class CustomResponseWrapper extends HttpServletResponseWrapper{
	private StringWriter stringWriter;
	private boolean isOutputStreamCalled;

	public CustomResponseWrapper(HttpServletResponse response) {
		super(response);
	}

	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		if (this.stringWriter != null) {
			throw new IllegalStateException("The getWriter() is already called.");
		}
		isOutputStreamCalled = true;
		return super.getOutputStream();
	}

	@Override
	public PrintWriter getWriter() throws IOException {
		if (isOutputStreamCalled) {
			throw new IllegalStateException("The getOutputStream() is already called.");
		}

		this.stringWriter = new StringWriter();

		return new PrintWriter(this.stringWriter);
	}

	public String getResponseContent() {
		if (this.stringWriter != null) {
			return this.stringWriter.toString();
		}
		return "";
	}
}

Sample filter class

Below is the sample filter which I have used to intercept the request so I can customize whatever content is written by the servlet or jsp. In this filter, I check the parameter “custom” which indicates that content should be customized or not. So we can apply the wrapper dynamically and check it’s effect runtime in browser. If the value of the “custom” parameter is true then the response would be converted to upper case otherwise the response wrapper would not be applied hence the response would be returned as it is.

package com.elitejavacoder.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.elitejavacoder.wrapper.CustomResponseWrapper;

/**
 * Servlet Filter implementation class SimpleFilter
 */
public class SimpleFilter implements Filter {

	public void init(FilterConfig filterConfig) throws ServletException {
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {

		boolean custom = false;
		if (request instanceof HttpServletRequest && response instanceof HttpServletResponse && ((HttpServletRequest)request).getParameter("custom") != null) {
			custom = Boolean.parseBoolean(((HttpServletRequest)request).getParameter("custom"));
		}

		if (custom) {
			CustomResponseWrapper wrapper = new CustomResponseWrapper((HttpServletResponse)response);
			filterChain.doFilter(request, wrapper);

			String originalResponse = wrapper.getResponseContent();
			System.out.println("Original Response: " + originalResponse);

			// Let's convert response content to upper case
			response.getWriter().print(originalResponse.toUpperCase());
		}
		else {
			filterChain.doFilter(request, response);
		}
	}

	public void destroy() {
	}
}

I have posted a complete sample application along with the instructions to run it on github. It is available at https://github.com/atulprajapati/samples/tree/master/custom-http-servlet-response-wrapper. You can try it yourself. Your questions and comments are welcome.