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
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.
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.
You can download the source code of this example here: Java EE Filter Design Pattern Example