First Hand on Servlet Filter

Servlet Filter is introduced in Servlet 2.3 specifications. It is explained as “A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses.”

Servlet Filter performs two main tasks

  1. transform the request
  2. modify the response

They are preprocessors of the request before it reaches a servlet, and/or postprocessors of the response leaving a servlet. You can configure a filter to act on a servlet or group of servlets. Zero or more filters can filter one or more servlets.

Here is the short tutorial to explain developing a simple filter for the Servlet. I have used NetBean for ease of development .

1. Create a Java Web App

2. Create sample Servlet 

  1: import java.io.IOException;
  2: import java.io.PrintWriter;
  3: import javax.servlet.ServletException;
  4: import javax.servlet.annotation.WebInitParam;
  5: import javax.servlet.annotation.WebServlet;
  6: import javax.servlet.http.HttpServlet;
  7: import javax.servlet.http.HttpServletRequest;
  8: import javax.servlet.http.HttpServletResponse;
  9: 
 10: /**
 11:  *
 12:  * @author Yogesh
 13:  */
 14: @WebServlet(name="HelloServlet", urlPatterns={"/HelloServlet1"}, initParams={@WebInitParam(name="name", value="Yogesh")})
 15: public class HelloServlet extends HttpServlet {
 16:   
 17:     protected void processRequest(HttpServletRequest request, HttpServletResponse response)
 18:     throws ServletException, IOException {
 19:         response.setContentType("text/html;charset=UTF-8");
 20:         PrintWriter out = response.getWriter();
 21:         String name = getInitParameter("name");
 22:         try {
 23:            // TODO output your page here
 24:             out.println("<html>");
 25:             out.println("<head>");
 26:             out.println("<title>Servlet HelloServlet</title>");  
 27:             out.println("</head>");
 28:             out.println("<body>");
 29:             out.println("<h2>Good Morning</h2>");
 30:             out.println("</body>");
 31:             out.println("</html>");
 32:             
 33:         } finally { 
 34:             out.close();
 35:         }
 36:     } 
 37: 
 38:    
 39:     @Override
 40:     protected void doGet(HttpServletRequest request, HttpServletResponse response)
 41:     throws ServletException, IOException {
 42:         processRequest(request, response);
 43:     } 
 44: 
 45: }


3. Create Filter using NetBean Wizard



2010-04-10_2338 



2010-04-10_2343




Next step allows us to add filter mapping URLs. This filter get invoked whenever these URLs accessed.



2010-04-10_2344





We have attached /HelloServlet1 to Demo Filter.



Here is the code for filter






4. Create Wrapper Class for Response –




As mentioned before, filter process request before reaching to Servlet and process response before it reach to browser/client. To get this done, we have to modify the request/response header and request  data by providing customized version of  the request object that wraps the request/response object.



We can accomplished by extending HttpServletResponseWrapper



Here We have created Wrapper for Response



  1: package demo.filter;
  2: 
  3: import java.io.CharArrayWriter;
  4: import java.io.PrintWriter;
  5: import javax.servlet.http.HttpServletResponse;
  6: import javax.servlet.http.HttpServletResponseWrapper;
  7: 
  8: /**
  9:  *
 10:  * @author ydevatra
 11:  */
 12: public class MyResponseWrapper extends HttpServletResponseWrapper{
 13: 
 14:     private CharArrayWriter writer = null;
 15:     public MyResponseWrapper(HttpServletResponse response){
 16:         super(response);
 17:         writer = new CharArrayWriter();
 18: 
 19:     }
 20: 
 21:     @Override
 22:     public PrintWriter getWriter(){
 23:         return new PrintWriter(writer);
 24:     }
 25: 
 26:     public String toString(){
 27:         return writer.toString();
 28:     }
 29: 
 30: }
 31: 



5. Code for Demo Filter



  1: /*
  2:  * To change this template, choose Tools | Templates
  3:  * and open the template in the editor.
  4:  */
  5: 
  6: package demo.filter;
  7: 
  8: import java.io.IOException;
  9: import javax.servlet.Filter;
 10: import javax.servlet.FilterChain;
 11: import javax.servlet.FilterConfig;
 12: import javax.servlet.ServletException;
 13: import javax.servlet.ServletRequest;
 14: import javax.servlet.ServletResponse;
 15: import javax.servlet.annotation.WebFilter;
 16: import javax.servlet.http.HttpServletResponse;
 17: 
 18: 
 19: /**
 20:  *
 21:  * @author Yogesh
 22:  */
 23: @WebFilter(filterName="DemoFilter", urlPatterns={"/HelloServlet"})
 24: public class DemoFilter implements Filter {
 25: 
 26:     private static final boolean debug = true;
 27: 
 28:     // The filter configuration object we are associated with.  If
 29:     // this value is null, this filter instance is not currently
 30:     // configured. 
 31:     private FilterConfig filterConfig = null;
 32: 
 33:     public DemoFilter() {
 34:     } 
 35:   
 36:     public void doFilter(ServletRequest request, ServletResponse response,
 37:                          FilterChain chain)
 38: 	throws IOException, ServletException {
 39: 
 40: 	try {
 41:             //Create wrapper for servlet response so that filter can alter it later
 42:             MyResponseWrapper wrapper = new MyResponseWrapper((HttpServletResponse)response);
 43:             //Calling chain filter , it calls main servlet at the end of chain
 44: 	    chain.doFilter(request, wrapper);
 45:             //after executing servlet , we got response
 46:             String responseHtml = wrapper.toString();
 47:             // Getting html start position
 48:             StringBuffer sb = new StringBuffer();
 49:             int start = responseHtml.indexOf("<Body>")+ 6;
 50:             sb.append(responseHtml.subSequence(0, start));
 51:             sb.append("<h1> Hello Yogesh</h1>");
 52:             sb.append(responseHtml.substring(start+1,responseHtml.length()));
 53:             //Writting to
 54:             response.getWriter().append(sb.toString());
 55: 	}
 56: 	catch(Throwable t) {
 57: 	    // If an exception is thrown somewhere down the filter chain,
 58: 	    // we still want to execute our after processing, and then
 59: 	    // rethrow the problem after that.
 60: 	    t.printStackTrace();
 61: 	}
 62:     }
 63:     
 64:    
 65:     public void destroy() { 
 66:     }
 67: 
 68:     public void init(FilterConfig filterConfig) { 
 69: 	this.filterConfig = filterConfig;
 70:      }
 71: }
 72: 



Here we have created Response wrapper and sent forward for further processing by calling chain.doFilter(request,wrapper). Please note that we have sent request-wrapper pair instead of request-response. When request get processed at servlet and control get back to filter we will have response at wrapper. We are extracting response string from wrapper and preparing response for client/browser.






Following sequence diagram will help to understand flow




2010-04-11_0024




6. Response is



2010-04-11_0026

Comments

Popular posts from this blog

Composite Design Pattern by example

State Design Pattern by Example

Eclipse command framework core expression: Property tester