Spring Boot Filter Example

By Arvind Rai, December 04, 2023
A Filter is 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.

1. 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;
   }   
   ------
} 
Find the filters used in above JavaConfig.
ABCFilter.java
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
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() {
	}
} 

2. 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. 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
@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. Output

Download the source code and 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 

7. References

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

8. Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us