Filters are objects that are installed [Figure 20.12:] between the client and the server to inspect requests and responses. They can transform the request or modify the response or both. Note that filters are not servlets and hence cannot create actual responses. Filters process requests before they reach a servlet and/or process responses after leaving a servlet. In general, a filter can do the following:
- Intercept and inspect requests before dispatching them to the servlets
- Modify requests’ headers and data and discard or filter requests
- Intercept and inspect responses before dispatching them to the clients
- Modify requests’ headers and data and discard or filter responses
A filter can work on behalf of a single servlet or a group of servlets. Similarly, zero or more filters can be installed for a servlet. Filters are typically used in the following areas:
- Authentication
- Logging and auditing
- Image compression
- Data compression
- Encryption
- Tokenization
- XML transformation
A filter class must implement the javax.serviet.Filter interface, which provides a framework for the filtering mechanism. It defines the following methods to be implemented by each filter class:
void init(FilterConfig config)
The web container, after instantiating a filter, calls this method once to install it and to set its configuration object. The method completes successfully; the filter can then start servicing. This method takes a FiiterConfig object that contains information that may be used to configure the filter.
The FiiterConfig interface provides methods to retrieve the filter’s name, its initialization parameters (specified in web.xml file) and the underlying servlet context.
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
This method is called every time a request from the client is passed through the filter. It takes three arguments: A ServletRequest type object request, a ServletResponse type object response and a FilterChain type object chain. The request and response objects encapsulate the client request and response respectively whereas chain represents the next filter in this chain of filters installed for the servlet. A usual implementation of this method is as follows:
Upon receiving the client request, it processes the request and takes necessary actions (e.g. changing/formatting the content or header etc.) as much as it can do. The filter should then hand over the control to the next filter in this chain by calling doFiiter() method on chain. The next filter takes further actions and forwards the request to the next filter in the chain. This way the client request propagates towards the servlet. If there is no further filter in the chain, the doFilter() on chain forwards the request to the servlet.
However, if a filter in the chain decides, it may not forward the request to the next filter; in this case, the request will not reach the servlet at all. In this way, filters can drop malicious requests intended for the servlet.
void destroy()
The method is called by the web container to uninstall the filter. Once this method is called on a filter, the doFilter() method is not called further, hence it stops functioning.
Let us now develop a simple filter that forwards only those requests that come from the host having the IP address “172.16.4.248”. Requests from all other hosts are discarded.
import java.io.*; import javax.servlet.*;
public class Firewall implements Filter {
private FilterConfig config = null;
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request.getRemoteAddr().equals(“172.16.4.248”)) chain.doFilter(request,
response);
}
public void destroy()
{
config = null;
}
}
Compile this file using the following command.
javac -cp d:\apache-tomcat-8.0.0-RC1\lib\servlet-api.jar Firewall.java
Note that the file servlet-api.jar is necessary to compile the above filter class. Put the Firewall. class file in the $TOMCAT_HOME\webapps\net\WEB-INF\classes directory.
1. Deploying Filter
To use this filter, you must specify it in the web.xml file using the <filter> tag.
<filter>
<filter-name>myFirewall</filter-name>
<filter-class>Firewall</filter-class>
</filter>
This notifies the server that a filter named myFirewall is implemented in the Firewall class. So, the web server creates an instance of this filter and installs it during start up. Now, add the following lines in the web.xml file.
<filter-mapping>
<filter-name>myFirewall</filter-name>
<url-pattern>/servlet/HelloWorld</url-pattern>
</filter-mapping>
This code states that a filter should function for the URL pattern /servlet/HelloWorld that corresponds to our HelloWorld servlet. Now, try accessing the HelloWorld servlet from a host having IP address 172.16.4.248. A response will be received as before. But, if the servlet is accessed from any machine other than 172.16.4.248, no response will be received.
Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.