Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for an example for inserting content into the response using a servlet filter

I've been searching the net and stackoverflow for an example of somebody inserting content into the response using a servlet filter, but can only find examples of people capturing/compressing the output and/or changing the headers. My goal is to append a chunk of HTML just before the closing </body> of all HTML responses.

I'm working on a solution that extends the HttpServletResponseWrapper to use my own PrintWriter, then overriding the write methods thereon. Inside the write method I'm storing the last 7 characters to see if it's equal to the closing body tag, and then I write my HTML chunk plus the closing body tag, before continuing normal write operations for the rest of the document.

I feel that somebody must have solved this problem already, and probably more elegantly than I will. I'd appreciate any examples of how to use a servlet filter to insert content into a response.

UPDATED

Responding to a comment, I am also trying to implement the CharResponseWrapper from http://www.oracle.com/technetwork/java/filters-137243.html. Here is my code:

PrintWriter out = response.getWriter(); CharResponseWrapper wrappedResponse = new CharResponseWrapper(         (HttpServletResponse)response);  chain.doFilter(wrappedRequest, wrappedResponse); String s = wrappedResponse.toString();  if (wrappedResponse.getContentType().equals("text/html") &&         StringUtils.isNotBlank(s)) {     CharArrayWriter caw = new CharArrayWriter();     caw.write(s.substring(0, s.indexOf("</body>") - 1));     caw.write("WTF</body></html>");     response.setContentLength(caw.toString().length());     out.write(caw.toString()); } else {     out.write(wrappedResponse.toString()); }  out.close(); 

I am also wrapping the request, but that code works and shouldn't affect the response.

like image 487
matt snider Avatar asked Feb 06 '13 18:02

matt snider


People also ask

What is filter in servlet example?

A filter is an object that is invoked at the preprocessing and postprocessing of a request. It is mainly used to perform filtering tasks such as conversion, logging, compression, encryption and decryption, input validation etc. The servlet filter is pluggable, i.e. its entry is defined in the web.

What do you mean by filtering request and response in servlet?

A filter is an object that can transform the header and content (or both) of a request or response. Filters differ from web components in that filters usually do not themselves create a response.

What is the use of servlet Filter?

Servlet Filters are pluggable java components that we can use to intercept and process requests before they are sent to servlets and response after servlet code is finished and before container sends the response back to the client.

Which method is used to set the content type of the response being sent to the client?

setContentType. Sets the content type of the response being sent to the client, if the response has not been committed yet. The given content type may include a character encoding specification, for example, text/html;charset=UTF-8 .


1 Answers

The codebase I am using, calls the getOutputStream method, instead of getWriter when it processes the response, so the examples included in the other answer doesn't help. Here is a more complete answer that works with both the OutputStream and the PrintWriter, even erroring correctly, if the writer is accessed twice. This is derived from the great example, DUMP REQUEST AND RESPONSE USING JAVAX.SERVLET.FILTER.

import javax.servlet.*; import javax.servlet.http.*; import java.io.*;  public class MyFilter implements Filter {     private FilterConfig filterConfig = null;      private static class ByteArrayServletStream extends ServletOutputStream     {         ByteArrayOutputStream baos;          ByteArrayServletStream(ByteArrayOutputStream baos)         {             this.baos = baos;         }          public void write(int param) throws IOException         {             baos.write(param);         }     }      private static class ByteArrayPrintWriter     {          private ByteArrayOutputStream baos = new ByteArrayOutputStream();          private PrintWriter pw = new PrintWriter(baos);          private ServletOutputStream sos = new ByteArrayServletStream(baos);          public PrintWriter getWriter()         {             return pw;         }          public ServletOutputStream getStream()         {             return sos;         }          byte[] toByteArray()         {             return baos.toByteArray();         }     }      public class CharResponseWrapper extends HttpServletResponseWrapper     {         private ByteArrayPrintWriter output;         private boolean usingWriter;          public CharResponseWrapper(HttpServletResponse response)         {             super(response);             usingWriter = false;             output = new ByteArrayPrintWriter();         }          public byte[] getByteArray()         {             return output.toByteArray();         }          @Override         public ServletOutputStream getOutputStream() throws IOException         {             // will error out, if in use             if (usingWriter) {                 super.getOutputStream();             }             usingWriter = true;             return output.getStream();         }          @Override         public PrintWriter getWriter() throws IOException         {             // will error out, if in use             if (usingWriter) {                 super.getWriter();             }             usingWriter = true;             return output.getWriter();         }          public String toString()         {             return output.toString();         }     }      public void init(FilterConfig filterConfig) throws ServletException     {         this.filterConfig = filterConfig;     }      public void destroy()     {         filterConfig = null;     }      public void doFilter(             ServletRequest request, ServletResponse response, FilterChain chain)             throws IOException, ServletException     {         CharResponseWrapper wrappedResponse = new CharResponseWrapper(                 (HttpServletResponse)response);          chain.doFilter(request, wrappedResponse);         byte[] bytes = wrappedResponse.getByteArray();          if (wrappedResponse.getContentType().contains("text/html")) {             String out = new String(bytes);             // DO YOUR REPLACEMENTS HERE             out = out.replace("</head>", "WTF</head>");             response.getOutputStream().write(out.getBytes());         }         else {             response.getOutputStream().write(bytes);         }     } } 
like image 125
matt snider Avatar answered Sep 29 '22 20:09

matt snider