You are on page 1of 26

Servlet Filters

So what is a Filter?
 Filters are java components that stand between a request and the intended endpoint of that request. The endpoint could be a static or dynamic resource such as a HTML page, a Servlet or a JSP.

How Filters help?


Request Filters can
 Perform security checks  Modify Request Headers and Data  Audit or log requests

Response Filters can


 Compress response stream  Alter the response stream  Generate its own response before returning to the client

The Filter Life Cycle


 Every Filter must implement the three methods of the Filter Interface: init(), doFilter() and destroy().

Filter Life Cycle(contd..)


 The init() method is invoked when the container first loads the Filter.It is passed a reference to the FilterConfig object.  The destroy() method is called when the Filter is unloaded from memory.  The doFilter() method is called every time the container determines that the filter should be applied to the current request. It takes three arguments:  A ServletRequest object  A ServletResponse object  A FilterChain

HitCounter Filter Example


public final class HitCounterFilter implements Filter { private FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void destroy() { this.filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

HitCounter Filter Example(contd..)


if (filterConfig == null) return; StringWriter sw = new StringWriter(); PrintWriter writer = new PrintWriter(sw); Counter counter = (Counter) filterConfig.getServletContext().getAttribute(hitCounter); writer.println(); writer.println("The number of hits is: + counter.incCounter()); writer.flush(); System.out.println(sw.getBuffer().toString()); chain.doFilter(request, wrapper); } }

FilterConfig Interface
getFilterName() Returns the filter-name of this filter as defined in the deployment descriptor. java.lang.String getInitParameter(java.lang.String name) Returns a String containing the value of the named initialization parameter, or null if the parameter does not exist. java.util.Enumeration getInitParameterNames() Returns the names of the filter's initialization parameters as an Enumeration of String objects, or an empty Enumeration if the filter has no initialization parameters. ServletContext getServletContext() Returns a reference to the ServletContext in which the caller is executing.

doFilter() method
A typical implementation of this method would follow the following pattern:1. Examine the request 2. Optionally wrap the request object with a custom implementation to filter content or headers for input filtering 3. Optionally wrap the response object with a custom implementation to filter content or headers for output filtering 4. a) Either invoke the next entity in the chain using the FilterChain object (chain.doFilter()), 4. b) or not pass on the request/response pair to the next entity in the filter chain to block the request processing 5. Directly set headers on the response after invocation of the next entity in the filter chain.

Filter Chaining
 Filters provide a mechanisms for applying layers of functionality to a ServletRequest and ServletResponse.  The DD controls the order in which filters are run.  A filter chain object represents the a chain of Filters an application is configured to use for a particular end point.

Filter Configuration
 Declare the Filter  Map the Filter to the web resources that you want to filter  Arrange the mappings to create filter invocation sequences.

Declaring a Filter
<filter> <filter-name>BookRequest</filter-name> <filter-class>com.example.BookRequestFilter</filter-class> <init-param> <param-name>login_page</param-name> <param-value>login.jsp</param-value> </init-param> </filter>

Declaring a filter mapping


<filter-mapping> <filter-name>BookRequest</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> <filter-mapping> <filter-name>BookRequest</filter-name> <servlet-name>BookRequestServlet </servlet-name> </filter-mapping>

Containers rules for ordering


 All filters matching URL patterns are located first. Filters with matching URL patterns are placed in the chain in the order in which they are declared in the DD.  All filters that have a matching <servlet-name> are placed in the chain in the order in which they are declared in the DD.

Declaring a filter mapping for request dispatched web resource


<filter-mapping> <filter-name>LogFilter</filter-name> <url-pattern>*.do</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>  INCLUDE  FORWARD  ERROR

Contd..
 If no dispatcher is specified, REQUEST is the default.  An INCLUDE value activates the filter for request dispatching from an include() call  A FORWARD value activates the filter for request dispatching from a forward() call  An Error value activates the filter for resources called by the error handler.

Compression?
Class MyCompressionFilter implements Filter { init(); public void doFilter(request, response, chain) { //request handling chain.doFilter(request, response); //do compression } }

Will it work?
NO Solution 1: Implementing our own response Drawback: Implement all methods in HttpServlet Response and its Super interface

Wrappers
 Wrapping is used to encapsulate a given request/response inside a customized one.  A wrapper is really just an implementation of the respective object that is wrapped Four Convenience classes that makes our job easier  ServletRequestWrapper  ServletResponseWrapper  HttpServletRequestWrapper  HttpServletResponseWrapper

Wrappers
 To override request methods, you wrap the request in an object that extends ServletRequestWrapper or HttpServletRequestWrapper. To override response methods, you wrap the response in an object that extends ServletResponseWrapper or HttpServletResponseWrapper.

The Real Compression Filter


package com.example; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.zip.GZIPOutputStream; public class CompressionFilter implements Filter { private ServletContext ctx; private FilterConfig cfg; public void init(FilterConfig cfg) throws ServletException { this.cfg = cfg; ctx = cfg.getServletContext(); }

Compression Filter
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fc) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; String valid_encodings = request.getHeader("Accept-Encoding"); if ( (valid_encodings != null) && (valid_encodings.indexOf("gzip") > -1) ) { CompressionResponseWrapper wrappedResp = new CompressionResponseWrapper(response); wrappedResp.setHeader("Content-Encoding", "gzip"); fc.doFilter(request, wrappedResp);

Compression Filter
GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream(); gzos.finish(); ctx.log(cfg.getFilterName() + ": finished the request."); } else { fc.doFilter(request, response); ctx.log(cfg.getFilterName() + ": no encoding performed."); } }

Summary

Questions

Thank You

You might also like