Enterprise Java

Java EE Filter Design Pattern Example

1. Introduction

Hi Java Code Geeks fan! This article is about a Java EE Filter Design Pattern Example. The filter pattern is used exetnsively in Java EE. It is most commonly used in combination with servlets. Servlets operate in the web layer and handle HTTP requests and responses. The role of filters is to perform some useful action against requests and responses.

2. Tools and Requirements

  1. Java 8
  2. WildFly 14.0.1
  3. Eclipse Oxygen
  4. Eclipse with WildFly and JBoss Tools Example

The source in this is example is based on the Java EE Web Project in Red Hat Central. We will not go through the details of setting up the project, so it is recommended that Eclipse with WildFly and JBoss Tools Example be read before trying out the example. We’ll be using WildFly 14.0.1 because it is a Java EE 8 full platform compatible implementation.

3. Java EE Filter Design Pattern Implementation

A servlet filter must implement the javax.servlet.Filter interface and associated methods. In older versions, it was necessary to implement the init method, the doFilter method, and the destroy method. Luckily, in Java EE 8, we only need to implement doFilter because the other are marked as default. The doFilter method is where all the magic happens.

4. @WebFilter

Import the java-ee-filtern-pattern project in Eclipse. Create the package org.jboss.examples.filter and add the LogFilter class.

LogFilter.java

package org.jboss.tools.examples.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

@WebFilter(filterName = "loggingFilter", urlPatterns ="/index.jsf/*")
public class LogFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;

		System.out.println("LOG: " + httpRequest); // method + URI

		chain.doFilter(request, response);

	}

}

In our method, we access the HTTP request and response instances. We can then apply any logic we want to it. In this example we are just simply printing it out to standard output. But we can do more than just log stuff. We can do authentication checks, compression, and so on. Filters can be chained together to provide consecutive functionality. This is why we have the chain.doFilter. We make sure that the request and response are passed on to the next filter or to the target servlet. The servlet performs its logic and when finished, execution is passed back up the filter chain through the filter, then back to the client.

We configured our filter with the @WebFilter annotation. It is a class level annotation. The most common options are the name, URL pattern and target servlets. For more options, check out the javadocs of WebFilter.

Running this web app (Run As -> Run on Server, WildFly 14.0.1), we will see in the console output something like this:

Console Output

11:32:39,438 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 2) WFLYSRV0016: Replaced deployment "java-ee-filter-pattern.war" with deployment "java-ee-filter-pattern.war"
11:53:48,671 INFO  [stdout] (default task-2) LOG: HttpServletRequestImpl [ GET /java-ee-filter-pattern/index.jsf ]

If you don’t see something like the above, try reloading the page.

Java EE Filter Design Pattern - Main Page
Main Page

5. web.xml

If we have more than one filter in the filter chain, they should be defined in the web.xml. The order of execution is the order in which they appear in the web.xml file. Let’s add another filter to log REST requests.RestFilter.java

package org.jboss.tools.examples.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

@WebFilter(filterName = "loggingFilter", urlPatterns ="/rest/members/*")
public class RestFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;

		System.out.println("REST: " + httpRequest); // method + URI

		chain.doFilter(request, response);

	}

}

It is more ore less the same as our first filter except for the console message which is “REST” and the URL pattern.

Next, we add the following lines in our web.xml.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1"
>
	<!-- Filters. NOTE: ordering of filter-mapping matters! -->

 	<filter>
		<filter-name>logFilter</filter-name>
		<filter-class>org.jboss.tools.examples.filter.LogFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>logFilter</filter-name>
		<url-pattern>/index.jsf/*</url-pattern>
	</filter-mapping>
	 
	<filter>
		<filter-name>restFilter</filter-name>
		<filter-class>org.jboss.tools.examples.filter.RestFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>restFilter</filter-name>
		<url-pattern>/rest/members/*</url-pattern>
	</filter-mapping>

</web-app>

When running our web app, we will see the “LOG” and “REST” messages (the request and resposne are passed on to the next filter) but after clicking on the REST URL, we will only see the “REST” message. This is because it does not match the URL pattern of the log filter anymore.

Console Output

12:45:38,101 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 14.0.1.Final (WildFly Core 6.0.2.Final) started in 7224ms - Started 494 of 666 services (328 services are lazy, passive or on-demand)
12:45:49,437 INFO  [stdout] (default task-1) LOG: HttpServletRequestImpl [ GET /java-ee-filter-pattern/index.jsf ]

12:45:49,437 INFO  [stdout] (default task-1) REST: HttpServletRequestImpl [ GET /java-ee-filter-pattern/index.jsf ]

12:45:49,802 INFO  [org.hibernate.hql.internal.QueryTranslatorFactoryInitiator] (default task-1) HHH000397: Using ASTQueryTranslatorFactory
12:49:06,356 INFO  [stdout] (default task-1) REST: HttpServletRequestImpl [ GET /java-ee-filter-pattern/rest/members/0 ]

12:49:06,357 INFO  [stdout] (default task-1) REST: HttpServletRequestImpl [ GET /java-ee-filter-pattern/rest/members/0 ]

6. Java EE Filter Design Pattern Summary

There you have it. Now you know the basics of the filter pattern in Java EE. Implement the filter interface and annotate the class with @WebFilter. If you have more than one filter, declare in the order you want them called in the web.xml. Simples!

7. Download the Source Code

This is an example about Java EE Filter Design Pattern.

Download
You can download the source code of this example here: Java EE Filter Design Pattern Example

Joel Patrick Llosa

I graduated from Silliman University in Dumaguete City with a degree in Bachelor of Science in Business Computer Application. I have contributed to many Java related projects at Neural Technologies Ltd., University of Southampton (iSolutions), Predictive Technologies, LLC., Confluence Service, North Concepts, Inc., NEC Telecom Software Philippines, Inc., and NEC Technologies Philippines, Inc. You can also find me in Upwork freelancing as a Java Developer.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button