Spring Boot Filter

By Arvind Rai, July 10, 2018
This page will walk through Spring Boot Filter example. A Filter can be registered using either FilterRegistrationBean class or @Component annotation or @ServletComponentScan annotation. FilterRegistrationBean registers a Filter as Spring bean and it provides methods to add URL mappings, set Filter order etc. When we register a Filter using Spring @Component, we can set Filter order using Spring @Order annotation but there is no way to change default URL mappings in this case. When we register Filter using @ServletComponentScan, our filters must be annotated with @WebFilter annotation and we can add URL mappings using its urlPatterns attribute but we cannot set Filter order in this case. @ServletComponentScan works only when using embedded server. Here on this page we will provide complete Spring Boot Filter example with filters, servlets and Spring controller.

1. Technologies Used

Find the technologies being used in our example.
1. Java 9
2. Spring 5.0.7.RELEASE
3. Spring Boot 2.0.3.RELEASE
4. Maven 3.5.2
5. Eclipse Oxygen

2. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.concretepage</groupId>
	<artifactId>spring-boot-app</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>spring-boot-app</name>
	<description>Spring Boot Application</description>

	<parent>
	   <groupId>org.springframework.boot</groupId>
	   <artifactId>spring-boot-starter-parent</artifactId>
	   <version>2.0.3.RELEASE</version>
	   <relativePath/>
	</parent>
	<properties>
	   <java.version>9</java.version>
	</properties>
	<dependencies>
	   <dependency>
	      <groupId>org.springframework.boot</groupId>
	      <artifactId>spring-boot-starter-web</artifactId>
	   </dependency>	
           <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-devtools</artifactId>
              <optional>true</optional>
           </dependency>
	</dependencies> 
	<build>
	   <plugins>
	      <plugin>
	  	 <groupId>org.springframework.boot</groupId>
	 	 <artifactId>spring-boot-maven-plugin</artifactId>
	      </plugin>
	   </plugins>
	</build>
</project> 

3. Register Filter with FilterRegistrationBean

FilterRegistrationBean registers filters in Servlet 3.0 + container. FilterRegistrationBean registers a filter as Spring bean. Find some of its methods.
setFilter(): Sets filter object.
addUrlPatterns(): Adds filter URL mappings.
setOrder(): Sets filter order.

Find the JavaConfig to register ABCFilter and XYZFilter classes.
WebConfig.java
@Configuration
public class WebConfig {
   //Register ABCFilter 	
   @Bean
   public FilterRegistrationBean<ABCFilter> abcFilter() {
	   FilterRegistrationBean<ABCFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new ABCFilter());
	   filterRegBean.addUrlPatterns("/app/*");
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);
	   return filterRegBean;
   }
   //Register XYZFilter   
   @Bean
   public FilterRegistrationBean<XYZFilter> xyzFilter() {
	   FilterRegistrationBean<XYZFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new XYZFilter());
	   filterRegBean.addUrlPatterns("/app/*");	
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2);
	   return filterRegBean;
   }   
   ------
} 

3.1. Filter URL Patterns

To add filter URL patterns we can use addUrlPatterns() or setUrlPatterns() methods of FilterRegistrationBean. Suppose we want to define URL patterns as /app1/* and /app2/* using addUrlPatterns(), it is achieved as following.
filterRegBean.addUrlPatterns("/app1/*", "/app2/*"); 
If we are using setUrlPatterns(), it is achieved as following.
filterRegBean.setUrlPatterns(Arrays.asList("/app1/*", "/app2/*")); 

3.2. Filter Order

When we register filters using FilterRegistrationBean, we can set filter order using its setOrder() method. Find the code snippet.
filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE); 
Ordered.HIGHEST_PRECEDENCE: This is the highest precedence.
Ordered.LOWEST_PRECEDENCE: This is the lowest precedence.

Lower the order number, higher the precedence. Find the sample precedence order.
Example-1:
Ordered.LOWEST_PRECEDENCE -2 > Ordered.LOWEST_PRECEDENCE -1 
Example-2:
Ordered.HIGHEST_PRECEDENCE +1 > Ordered.HIGHEST_PRECEDENCE +2 
It is usually safe to leave the filter beans unordered. Spring boot provides them default order and that is usually Ordered.LOWEST_PRECEDENCE. If we want to run our custom filters before or after any in-built filter such as Spring security filter, we need to order them using FilterRegistrationBean. It means if we want to run our custom filter after Spring security filter, we need to create our own FilterRegistrationBean for Spring security filter and specify the order.

4. Register Filter with @Component and @Order

We can register a filter using @Component and set order using @Order. Create a filter implementing Java Filter and annotate it with Spring @Component as following.
ABCFilter.java
@Order(Ordered.LOWEST_PRECEDENCE -1)
@Component
public class ABCFilter implements Filter {
  ------
} 
XYZFilter.java
@Order(Ordered.LOWEST_PRECEDENCE -2)
@Component
public class XYZFilter implements Filter {
  ------
} 
Filter Order
When we register filter using @Component, we can use Spring @Order annotation to set filter order as
@Order(Ordered.LOWEST_PRECEDENCE) 
Filter URL Patterns cannot be set with @Component
The default filter URL pattern is "/*". We cannot change it in case we register filter with @Component annotation. If we want filter URL mappings, we should register filters using FilterRegistrationBean.

5. Register Filter with @ServletComponentScan and @WebFilter

To register a filter in Spring Boot, we can use @ServletComponentScan and the filter should be annotated with @WebFilter annotation. We need to use @ServletComponentScan with @Configuration or @SpringBootApplication annotations. @ServletComponentScan in Spring Boot will scan servlets annotated with @WebServlet, filters annotated with @WebFilter and listeners annotated with @WebListener only when using an embedded web server. Suppose we have two filters annotated with @WebFilter as following.
ABCFilter.java
@WebFilter(urlPatterns="/app/*")
public class ABCFilter implements Filter {
  ------
} 
XYZFilter.java
@WebFilter(urlPatterns="/app/*")
public class XYZFilter implements Filter {
  ------
} 
Now use Spring boot starter Main class with@ServletComponentScan to scan above filters.
SpringBootAppStarter.java
package com.concretepage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@ServletComponentScan
@SpringBootApplication
public class SpringBootAppStarter {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAppStarter.class, args);
    }
} 
Filter URL Patterns
The annotation @WebFilter has the attribute urlPatterns to map URLs as following.
@WebFilter(urlPatterns= {"/app1/*", "/app2/*"})
public class ABCFilter implements Filter {
   ------
} 
Filter Order cannot be set with @WebFilter
When we register filters using @WebFilter then we cannot order them in Spring Boot. @WebFilter does not provide any attribute to set order. We also cannot use Spring @Order annotation, because Spring does not identify @WebFilter annotated class as Spring bean. @WebFilter is a Java annotation and not a Spring annotation. If we want to set order we should register our filters using FilterRegistrationBean.

6. Complete Example: Spring Boot Filter Mapping with FilterRegistrationBean

We will provide here Spring Boot filter complete example with FilterRegistrationBean class. We will create two filters, two servlets and one Spring controller with a method in our demo application. We will register filters using FilterRegistrationBean and servlets using ServletRegistrationBean class in a JavaConfig. Now find the complete example.
Find the project structure of demo application.
Spring Boot Filter
Now find the Java files.
ABCFilter.java
package com.concretepage.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class ABCFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		System.out.println("Inside ABCFilter: "+ req.getRequestURI());
		chain.doFilter(request, response);
	}
	@Override
	public void destroy() {
	}
} 
XYZFilter.java
package com.concretepage.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class XYZFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		System.out.println("Inside XYZFilter: "+ req.getRequestURI());
		chain.doFilter(request, response);
	}
	@Override
	public void destroy() {
	}
} 
HelloCountryServlet.java
package com.concretepage.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloCountryServlet extends HttpServlet   {
	private static final long serialVersionUID = 1L;
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
	    doGet(request,response);
	}
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
	    out.println("<h3>Hello India!</h3>");	
	}
} 
HelloStateServlet.java
package com.concretepage.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloStateServlet extends HttpServlet   {
	private static final long serialVersionUID = 1L;
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
	   doGet(request,response);
	}
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
           response.setContentType("text/html");
           PrintWriter out = response.getWriter();
	   out.println("<h3>Hello Uttar Pradesh!</h3>");	
	}
} 
WebConfig.java
package com.concretepage;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import com.concretepage.filters.ABCFilter;
import com.concretepage.filters.XYZFilter;
import com.concretepage.servlets.HelloCountryServlet;
import com.concretepage.servlets.HelloStateServlet;

@Configuration
public class WebConfig {
   //Register ABCFilter 	
   @Bean
   public FilterRegistrationBean<ABCFilter> abcFilter() {
	   FilterRegistrationBean<ABCFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new ABCFilter());
	   filterRegBean.addUrlPatterns("/app/*");
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);
	   return filterRegBean;
   }
   //Register XYZFilter   
   @Bean
   public FilterRegistrationBean<XYZFilter> xyzFilter() {
	   FilterRegistrationBean<XYZFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new XYZFilter());
	   filterRegBean.addUrlPatterns("/app/*");	
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2);
	   return filterRegBean;
   }   
   
   //Register HelloCountryServlet   
   @Bean	
   public ServletRegistrationBean<HelloCountryServlet> countryServlet() {
	   ServletRegistrationBean<HelloCountryServlet> servRegBean = new ServletRegistrationBean<>();
	   servRegBean.setServlet(new HelloCountryServlet());
	   servRegBean.addUrlMappings("/app/country/*");
	   servRegBean.setLoadOnStartup(1);
	   return servRegBean;
   }
   //Register HelloStateServlet   
   @Bean	
   public ServletRegistrationBean<HelloStateServlet> stateServlet() {
	   ServletRegistrationBean<HelloStateServlet> servRegBean = new ServletRegistrationBean<>();
	   servRegBean.setServlet(new HelloStateServlet());
	   servRegBean.addUrlMappings("/app/state/*");
	   servRegBean.setLoadOnStartup(1);
	   return servRegBean;
   }   
} 
HelloWorldController.java
package com.concretepage.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {     
	
    @RequestMapping("/app/world")
    public String helloMsg() {
    	String msg = "Hello World!";
        return msg;
    }
} 
SpringBootAppStarter.java
package com.concretepage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootAppStarter {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAppStarter.class, args);
    }
} 

7. Test Application

We can run our Spring Boot application in following ways.
1. Using Maven Command: Download the project source code. Go to the root folder of the project using command prompt and run the command.
mvn spring-boot:run 
Tomcat server will be started.

2. Using Eclipse: Download the project source code using the download link given at the end of article. Import the project into eclipse. Using command prompt, go to the root folder of the project and run.
mvn clean eclipse:eclipse 
and then refresh the project in eclipse. Run Main class SpringBootAppStarter by clicking Run as -> Java Application. Tomcat server will be started.

3. Using Executable JAR: Using command prompt, go to the root folder of the project and run the command.
mvn clean package 
We will get executable JAR spring-boot-app-0.0.1-SNAPSHOT.jar in target folder. Run this JAR as
java -jar target/spring-boot-app-0.0.1-SNAPSHOT.jar 
Tomcat server will be started.

Now we are ready to test the application. Run the following URL.
http://localhost:8080/app/country 
We will get following output in console.
Output
Inside XYZFilter: /app/country
Inside ABCFilter: /app/country 
Run the following URL.
http://localhost:8080/app/state 
Output
Inside XYZFilter: /app/state
Inside ABCFilter: /app/state 
Run the following URL.
http://localhost:8080/app/world 
Output
Inside XYZFilter: /app/world
Inside ABCFilter: /app/world 

8. References

Spring Boot Reference Guide
FilterRegistrationBean
@ServletComponentScan
Spring Boot Servlet Mapping
Filter installed ahead of spring security filters
@WebFilter and @Order

9. Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI









©2023 concretepage.com | Privacy Policy | Contact Us