21 Filters

Pravin Jain

epgp books

 

Introduction

 

In this module we will be looking at another type of component which can be used within a servlet container. We will be looking at Filters. Filters development wise, life cycle wise, looks similar to a Servlet. But it is not exactly a servlet. Servlets are resources there are url for servlets but filters dont corresponds to a url though we do map them to a url.

 

What are Filters?

 

Filters are more towards interceptor. Some kind of a interceptor for a request on the server side. Let us see the mechanism on how the filters work on the server side.

 

Filter is again an interface in the javax.servlet package. It can be used as an interceptor. It can be used in some kind of an authentication, it can also be used in transforms. It can be used for transforming the responses to the client. Method in the Filter are similsr to the Servlet methods. Servlet has those three life-cycle methods. Similarly Filter interface also has its own life-cycle methods. As we have ServletConfig for servlets, we here have FilterConfig. Let us see what all things are required for the filters so let see deployment descriptor for filters:

 

So, in web.xml we use to make <servlet> entries for the servlet and we also had corresponding <servlet-mapping>. Similar to the <servlet> and <servlet-mapping> whenever we want to use a Filter component we would be having the entry in the web.xml for a <filter> and a <filter mapping>. Similar to the entries made for <servlet> and <servlet mapping>. As we had <servlet-name> for <servlet- mapping> here we would have <filter-name>, we would have a <filter-class> no option of a jsp. So <filter> can have a entry called <filter-name>, <filter-class> which is nothing but an implementation of a Filter interface.

 

And then you can have Filter specific parameter which you would like the Filter to use. So if you have any Filter specific parameter to use we have that <init-param> entry just like we had <init-param> entry for the Servlet. we had <init-param> entry containing <param-name> and <param-value> within a <filter> entry. Any number of <init-param> entries may be specified for filters. So these are different filter objects which would be created. Each of these filter objects they come into the picture.

 

We in servlet-mapping were defining <url-pattern>s which become valid for this application but the filter-mapping is not defining any new <url-pattern> but you need to give here the existing url. The <filter-mapping> is not for creating the new url. It is nothing but the interceptor for these kind of urls. For eg. i want to have a Filter which is for *.hello. If someone is using this kind of *.hello url i would like that request to go through these filter. I want the filter to be applied even before the request is started to be processed by a servlet. So these are basically interceptor to a request these are not the end points to a resource. These are interceptor to the resources. If some one is trying to fetch particular type of resource you can give in filter-mapping that this specific filter should be applied before you start using particular resource. That is why we are giving in filter-mapping a filter-name and a url- pattern. url pattern here is not defining a new url but saying that this filter should be applied for this particular url.

 

Let us see what exactly happens. Another thing which is different about filters compared to the servlet

 

as far as servlet is concerned, servlet may or may not be loaded on start up where initialization may not even take place because they don’t have a load-onpstartup and no client even access that resource those objects were never created. As far as filters are concerned filters are going to load as soon as we start the application, when the web container starts a particular application during the start up of an application the filter objects would be created.

 

There is something more with the filter objects, there are few other interfaces which are defined here: FilterChain – it is an interface stated as sequence of filters. When the url hits the server this url is identified there might be multiple filter entries which qualifies for this url and on this url there might be some resource which qualifies. If there is no resource which qualifies no filter is applicable here. Whatever is being targeted as a resource must be a valid resource. You may have servlet/html/static content as an resource but not Filter as an resource. If the url is going to hit the server the servers have identified which filters are applicable provided that is a valid resource and not simply a filter which filters become applicable to this. So first ServletRequest and ServletResponse object needs to be created because it is something that should be done by the container next it has already identified which all filters become applicable here. Now when it has identified that these are all filters which are applicable it would create an object of FilterChain.

 

FilterChain is nothing but all those filters put together in that sequence first filter, second filter, third filter. If there are three filters for a particular request applicable, it would put those three filters in a sequence at the end of the third filter in the FilterChain it keeps the target resource. For example if the target is the HelloServlet by the particular filter, you might have configured N number of filters. Let us say we configured 5 filter in our application but may be for this url three of those are applicable. So FilterChain would be created with three filter objects. In the chain it would say first filter object as filter1, second filter object as an filter2 and third filter object as an filter3 and the fourth thing here is the target resource that is HelloServlet. Once it has identified this it will then invoke and FilterChain has been created. Now this FilterChain interface only provides one method called doFilter:

 

public void doFilter(ServletRequest req, ServletResponse res)

 

The way FilterChain’s doFilter() method works is like when this FilterChain created it has four elements here, first three are the filters and then the targeted resource. In this case it would pick up the first of them and invoke the regular lifecycle method. The Filter like our Servlet has three life-cycle method:

 

public void init(FilterConfig config) used during the startup phase. public void doFilter(ServletRequest request, ServletResponse response) public void destroy()

 

FilterConfig is similar to ServletConfig making available the Filter name, init parameter and the ServletContext. FilterChain identifies the first filter, the regular life-cycle method of the filter is also called doFilter() but here it has three parameters:

 

–  ServletRequest

–  ServletResponse

–  FilterChain

 

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)

 

When the doFilter method is invoked on the filter what the filter has, the filter is made available the request and the response object. Looking at the request we can understand what has been targetted by the url. The request object is available to the filter. If filter wants to do any kind of checking it can do, there can be some blacklist like this filter is used to prevent some blacklist which can restrict the client to reach the server. ServletRequest has the method to know who is the remote user, it can know the remote IP address. It has method to get the remote host. So this filter may use such methods and like to take some action whether may be I would like to let the request proceed further or I would like to prevent this request from proceeding further. If it wants to prevent the request from proceeding further it can use the response object here itself and can give the response back. I can use some sendError() method and send the response back. You can cast the ServletResponse object to HttpServletResponse object and use the methods These parameters which are used here are HttpServletRequest and HttpServletResponse since the protocol being followed is the Http protocol. So one option is like I want to prevent it from going further give a response here itself.

 

Other option is when the doFilter method has been invoked we have request and response object but there is a third parameter i.e. FilterChain. The chain whose part this filter is. This filter is part of a chain. This chain has identified this as the first filter, so this chain object is available to the filter also, whose part it is. Now, the other option if the filter decide that I would like to proceed further, I would like to let the request proceed furher then, what the filter could do here is, that within the doFilter() method the third parameter, which is the FilterChain object, on that, it can simply invoke the method doFilter() again. What is this doFilter on a FilterChain doing. Whenever it is invoked, it is simply identifying the next element. The next element may be, if it is the final element it is a resource otherwise it is a Filter, and on that it is invoking the regular life cycle method. On Filter, it is going to call the doFilter() method with the three parameters where the third parameter would be chain itself. If it is a final element and if someone is calling doFilter method on it and if the next element is the servlet then it will be calling the service method. Each time doFilter on a FilterChain would result in invocation of the regular life-cycle method on the next element. If it is a filter element which are the initial element it will be the doFilter method or if it is a final element and if it is a servlet it will invoke the service method. So, this is how it works, it is just fetching the next element and invoking the life- cycle method. That is how the FilterChain works.

 

The interesting part of the Filter here is when you write the code and write the doFilter method, we are initially getting the request and the response object plus we are getting the FilterChain object. We ar,e doing some processing initially. in this processing we are free to say we don’t want to proceed further and give the response right there itself. We are even free to modify the request like we can modify the url, add some attributes into it so that it can be used in some other components. Some preprocessing you may be doing with the request object, once finish with the preprocessing and if it is valid you may want to proceed further before we call to chain.doFilter(). When you call chain.doFilter() it goes to the next one.

 

The next filter processing is also done let say preprocessing has been done. In preprocessing it might have done something but there is again doFilter there. Suppose we invoke doFilter and there is no more filter left then it is going to the target resource.

 

The targeted resource might have generated some kind of response, that response is given back to the chain.doFilter(). It was a chain.doFilter() method in the doFilter() method. We have a preprocessing and then we have a chain.doFilter().

 

It is the second filter whose chain.doFilter() finishes once the response has been generated from the resource. The life-cycle of the resource is over the control is back to the filter number 2. It is now going to proceed further whatever is left out after the invocation of chain.doFilter.

 

So you can see here that our doFilter method of a Filter is divided into two parts. There is a preprocessing part, there is an invocation of chain.doFilter() letting it go further and there is a post processing part. Post-processing is like once the processing is done by the resource then the next steps are the one which you write after the chain.doFilter(). If we want some transformation of the responses to be done that is something which can be managed in the post-processing.

 

In pre and post processing there can be some other kind of information like login information or logout information. The advantage here is one can transform the response which is generated by resource and in order to do the transformation of the response which is generated by the resource, there are more efforts needed here.

 

Whenever the service method of the servlet finishes, it would be entering that post-processing part but if we observe the post processing part, as soon as the service method is finished basically what we find is the response has actually been committed. You would not be allowed to modify it. So you cannot transform the response to a great extent since response is already committed. There are few things which has to be changed here.

 

When I call chain. doFilter is it necessary that i use the same response object, its not necessary that chain.doFilter uses the same response. It can create its own request and response object and give it to the next. So what could be done here if someone is interested in transforming the response. The filter in the implementation can create its own object of response. We have the class available for that so we need not to worry about implementing all the method of the response. There are two class for that:

 

One in the generic part which is, javax.servlet package, where we have a class called ServletResponseWrapper and ServletRequestWrapper.

 

In javax.servlet.Http package we also have classes called HttpServletRequestWrapper and HttpServletResponseWrapper.

 

These classes have constructor that take parameters as the request and the response. It acts as a wrapper for an existing http request object. I am only interested in transforming the response which comes a client. I may create the subclass of the HttpServletRequestWrapper and override the getWriter method and I don’t know here the servlet is going to generate the response using the getWriter method. If it is going to write using the getWriter method then i would like to change for him, so that if he writes using the method getWriter he does not write into the response, rather i have created the object where i can force him to write something in the buffer of my own. We have the StringWriter object so StringBuffer would be used internally to write getWriter object which returns PrintWriter object. So anything which is returned by the servlet does not go directly into the response buffer of the container but rather it goes into the StringWriter object which we created. So we could have our own class i.e. subclass of the ServletResponseWrapper which is overriding the getWriter method, so that getWriter does not write into the buffer of the response but writes to the’ StringWriter object so such thing can be used in the post-processing part further code then be examine then be used to write into the actual object which is available from the container.

 

So that way even post-processing is possible with the purpose of making transformation in the responses  which  are  generated  from  the  servlet.  So  you  may  have  number  of  filters  which  are available, the way the execution proceeds in the filter is, url targets a particular resource, the filters which have been identified for that resource would be put in the sequence using a filter chain object. The life cycle methods that is the two filter methods are getting invoked on each of those objects. So if it is identified as filter1, filter2, filter3 the two filter on filter1 is invoked, the pre-processing finished which is on filter1, chain.doFilter() results in invocation of the pre-processing of filter2. It finishes the pre-processing of the filter2. chain.doFilter() of filter2 results in proceeding to the invocation of filter3, it finishes with pre-processing of filter3. chain.doFilter() results in invocation of service of the servlet. Once the service of the servlet finishes it proceeds with the post-processing of filter3, which in turn goes back to the post-processing of filter2 and after finishing filter2 post-processing it will come back to the post-processing of filter1.

 

The doFilter() method is divided into pre and post-processing. It executes like pre-processing of filter1 then filter2 and so on.. and similar finishing the post processing of filter3 first then of filter2 and last of filter1. Request processing goes through the number of filters which we have setup in the web.xml. So we have filter lifecycle like wise of servlet:

 

public void init(FilterConig cfg)

public void doFilter(Request,Response, FilterChain)

public void destroy()

you can view video on Filters
Suggested Reading:
  1. Core Servlets and Java Server Pages Volume
  2. by Marty Hall & Larry Brown, Second Edition, Pearson Education.
  3. Inside Servlets by Dustin R Callaway, Pearson Education.
  4. Java Server Programming for Professionals by Ivan Bayross, Sharanam Shah, Cynhthia Bayross and Vaishali Shah Shroff Publishers and Distributros.
  5. http://download.oracle.com/otndocs/jcp/servlet-3.0-fr-oth-JSpec/