Spring Boot Filter Example
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; } ------ }
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() { } }
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 useaddUrlPatterns()
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/*");
setUrlPatterns()
, it is achieved as following.
filterRegBean.setUrlPatterns(Arrays.asList("/app1/*", "/app2/*"));
3. Filter Order
When we register filters usingFilterRegistrationBean
, 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
Ordered.HIGHEST_PRECEDENCE +1 > Ordered.HIGHEST_PRECEDENCE +2
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 { ------ }
@Order(Ordered.LOWEST_PRECEDENCE -2) @Component public class XYZFilter implements Filter { ------ }
When we register filter using
@Component
, we can use Spring @Order
annotation to set filter order as
@Order(Ordered.LOWEST_PRECEDENCE)
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 { ------ }
@WebFilter(urlPatterns="/app/*") public class XYZFilter implements Filter { ------ }
@ServletComponentScan
to scan above filters.
SpringBootAppStarter.java
@ServletComponentScan @SpringBootApplication public class SpringBootAppStarter { public static void main(String[] args) { SpringApplication.run(SpringBootAppStarter.class, args); } }
The annotation
@WebFilter
has the attribute urlPatterns
to map URLs as following.
@WebFilter(urlPatterns= {"/app1/*", "/app2/*"}) public class ABCFilter implements Filter { ------ }
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
Output
Inside XYZFilter: /app/country Inside ABCFilter: /app/country
http://localhost:8080/app/state
Inside XYZFilter: /app/state Inside ABCFilter: /app/state
http://localhost:8080/app/world
Inside XYZFilter: /app/world Inside ABCFilter: /app/world
7. References
Spring Boot Reference GuideFilterRegistrationBean
@ServletComponentScan
Filter installed ahead of spring security filters
@WebFilter and @Order