Java Servlet Filters

Kasun Dharmadasa
6 min readDec 17, 2017

--

Source: http://blog.inkjetwholesale.com.au/wp-content/uploads/2016/07/instagram-for-your-business-filters.jpg

Servlet Filters are used to intercept a request and conduct pre-processing or post-processing on that request. It is useful in implementing features such as

  1. Logging of requests
  2. Authentication and Authorization
  3. Encryption or Decryption
  4. Formatting the request header or body before sending to the servlet.

Filters can also be implemented in chains. The order of the filter chain can be defined using the deployment descriptor (web.xml).

Source : https://www.javatpoint.com/servlet-filter

In order to use filters, we have to implement the javax.servlet.Filter interface provided by java. This interface provides the following set of methods.

  1. init( FilterConfig config )
    This is a one-time method that gets invoked when the filter is initialized.
  2. doFilter(HttpServletRequest request,HttpServletResponse response, FilterChain chain)
    This method gets invoked every time when the filter has to filter a request. All the filter actions on the request can be implemented here. The FilterChain parameter can be used to implement the next filter in the filter chain.
  3. destroy()
    This is a one-time method that gets invoked when the filter is taken out of service.

Before implementing servlet filters, let’s create a sample webpage that accepts a request and display the content.

MovieHut.com

MovieHut is an online movie store. We’ll use a servlet to display the MovieHut webpage.

I’m using IntelliJ IDEA as my IDE and maven tomcat plugin to deploy the web app. (If you are not familiar with servlets or the tomcat maven plugin, refer my previous post on Sample Java Web Application using Servlets and JSP)

Step 1: Create a maven project.

Step 2: Add the servlet dependency and tomcat maven plugin to the pom.xml

Step 3: Create the MovieServlet class

Create a class named MovieServlet.java in src/main/java under the package name com.servlet and insert the following code.

The MovieServlet class accepts the GET request sent by the browser and load the Welcome page.In my previous tutorials, I have used Annotations to define the servlets. However, we’ll use a deployment descriptor (web.xml) to define this servlet.

Step 5: Create the web.xml

Create the WEB-INF directory under webapp directory and add the following web.xml file.

In this web.xml file, we define our MovieServlet class and map the URL pattern “/Servlets/MovieServlet”. All the other relevant servlets can be mapped under /Servlets.

Step 6: Build the war and deploy.

If you are using tomcat maven plugin, you can simply enter the following command in the terminal.

mvn tomcat7:run

This will automatically build the war file and deploy in tomcat.

If you browse to the http://localhost:8080/FilterSample/Servlets/MovieServlet

you will see the MovieHut.com welcome page.

Here “FilterSample” is the artifactID I have given for my maven project. maven tomcat plugin automatically gets the artifactID as the application path.

Let’s use Filters
The MovieHut team decided to log IP address and the timestamp of the requests coming to the servlets. There are several ways to achieve this. Since we are here to learn about servlet filters, we’ll use a servlet filter to fulfill the above requirement.

Step 8: Create the RequestLoggingFilter class

Create the class RequestLoggingFilter.java in src/main/java under the package name com.servlet.filters and add the following code.

In order to use this filter, we need to add the filter and its mapping to web.xml. To do that add the following code to the web.xml

<filter>
<filter-name>RequestLoggingFilter</filter-name>
<filter-class>com.servlet.filters.RequestLoggingFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>RequestLoggingFilter</filter-name>
<url-pattern>/Servlets/*</url-pattern>
</filter-mapping>

Here we have mapped this filter to the URL pattern /Servlets/* so that the requests start with /Servlets will be intercepted by this filter.

As explained in the beginning of this tutorial, RequestLoggingFilter has implemented the doFilter() method to intercept the request. This filter will log the IP address and the Timestamp of requests into ServletContext logs. These logs can be viewed from %TOMCAT_HOME/logs/localhost.$(date).log file.

If you deploy the war and press Enter in the index.html, you’ll see the request log in the terminal.

Adding multiple Filters

After all this, the MovieHut team needed to make MovieHut.com visible only for mobile users. They wanted to allow only mobile browsers to access the site. No need to panic. This requirement can also be achieved using Servlet filters.

You might have noticed that each HTTP request carries a User-Agent header consisting information of the browser and OS that originated the request. We can use this header to identify mobile browsers.

However, this approach is not recommended as the user has the ability to change the request headers by intercepting the requests (We’ll talk more about that in future articles).

A sample User-Agent header

We’ll use a library called UserAgentUtils to extract the required information from the User-Agent header. To import this library, add the following dependency into pom.xml.

<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.20</version>
</dependency>

Step 9: Create the RequestBlockingFilter class

Create the RequestBlockingFilter.java class in src/main/java/ under the package name com.servlet.filters and add the following code.

Remember to add the RequestBlockingFilter to the web.xml

<filter>
<filter-name>RequestBlockingFilter</filter-name>
<filter-class>com.servlet.filters.RequestBlockingFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>RequestBlockingFilter</filter-name>
<url-pattern>/Servlets/*</url-pattern>
</filter-mapping>

The RequestBlockingFilter will intercept all the requests to /Servlets and check the browser name that comes with the User-Agent header. For simplicity, I have blocked the Firefox browser (Let’s assume that all the desktop computers use Firefox browser). If the user agent is Firefox, the RequestBlockingFilter will redirect the user to the landing page with an error message.

If you deploy this sample and test it using the Firefox browser, you’ll get the following error message.

Note that the order of a filter is decided on the order they are defined in the web.xml. If you have defined the RequestBlockingFilter before RequestLoggingFilter (as shown below), you will notice that the requests from Firefox browsers will not be logged by the RequestLoggingFilter as they are not getting passed to the filter chain by RequestBlockingFilter.

<filter>
<filter-name>RequestBlockingFilter</filter-name>
<filter-class>com.servlet.filters.RequestBlockingFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>RequestBlockingFilter</filter-name>
<url-pattern>/Servlets/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>RequestLoggingFilter</filter-name>
<filter-class>com.servlet.filters.RequestLoggingFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>RequestLoggingFilter</filter-name>
<url-pattern>/Servlets/*</url-pattern>
</filter-mapping>

Servlet Filters are pluggable. We can easily remove any of the above filters by removing the filter mapping in the web.xml and redeploying the war.

References

--

--