Master Custom Servlet Filters in Spring Boot: Scope, Order, and Registration
Learn how to declare custom Servlet Filters in Spring Boot, control their execution order and URL scope using both manual bean definitions and Spring's FilterRegistrationBean, with complete code examples and best‑practice tips for secure, maintainable backend development.
1. Introduction
Sometimes we need to declare custom Servlet Filters in a Spring Boot servlet web application to handle logic such as simple permission checks, request‑header filtering, or XSS protection.
2. Custom Filter
Declaring a Servlet Filter is simply implementing the javax.servlet.Filter interface, but we often want the filter to apply only to specific requests and to execute in a defined order.
2.1 Filter declaration
In Spring Boot we can declare a Spring bean that implements javax.servlet.Filter:
@Configuration
public class FilterConfig {
@Bean
public Filter requestFilter() {
return (request, response, chain) -> {
// todo your business
};
}
@Bean
public Filter responseFilter() {
return (request, response, chain) -> {
// todo your business
};
}
}This approach applies the filter to all requests and does not guarantee execution order.
2.2 Implement filter ordering
We can use Spring's @Order annotation or implement the Ordered interface. To keep a Java‑config style we define an OrderedFilter interface that extends both Filter and Ordered:
@Configuration
public class FilterConfig {
@Bean
public OrderedFilter responseFilter() {
return new ResponseFilter("/foo/*");
}
@Bean
public OrderedFilter requestFilter() {
return new RequestFilter("/foo/*");
}
}Filters with smaller order values execute first.
2.3 Custom filter scope
After ordering, we can limit a filter to specific URL patterns using ANT‑style matching. An abstract base class can encapsulate this logic:
package cn.felord.springboot.filters;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
public abstract class AbstractFilterBean implements OrderedFilter {
private Set<String> urlPatterns = new LinkedHashSet<>();
public AbstractFilterBean(String... urlPatterns) {
Collections.addAll(this.urlPatterns, urlPatterns);
}
public abstract void internalHandler(ServletRequest request, ServletResponse response);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (this.antMatch(request)) {
this.internalHandler(request, response);
}
chain.doFilter(request, response);
}
private boolean antMatch(ServletRequest request) {
Set<String> urlPatterns = getUrlPatterns();
if (!CollectionUtils.isEmpty(urlPatterns)) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String uri = httpServletRequest.getRequestURI();
return urlPatterns.stream().anyMatch(s -> new AntPathMatcher().match(s, uri));
}
return true;
}
public Set<String> getUrlPatterns() {
return urlPatterns;
}
}A concrete filter that logs the request URI:
@Slf4j
public class RequestFilter extends AbstractFilterBean {
public RequestFilter(String... urlPatterns) {
super(urlPatterns);
}
@Override
public void internalHandler(ServletRequest request, ServletResponse response) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
log.info("request from {}", httpServletRequest.getRequestURI());
}
@Override
public int getOrder() {
return 0;
}
}Register the filter bean in the Spring IoC container, and set the order if multiple filters are needed.
3. Spring Boot registration mechanism
Spring Boot also provides a convenient FilterRegistrationBean to declare filters with order and URL patterns:
@Configuration
@Slf4j
public class SpringFilterRegistrationConfig {
@Bean
public FilterRegistrationBean<Filter> responseFilter() {
FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setName("responseFilter");
registrationBean.setOrder(2);
registrationBean.setFilter((request, response, chain) -> {
HttpServletResponse servletResponse = (HttpServletResponse) response;
log.info("response status {}", servletResponse.getStatus());
chain.doFilter(request, response);
});
registrationBean.addUrlPatterns("/foo/*");
return registrationBean;
}
@Bean
public FilterRegistrationBean<Filter> requestFilter() {
FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setName("requestFilter");
registrationBean.setOrder(1);
registrationBean.setFilter((request, response, chain) -> {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
log.info("request from {}", httpServletRequest.getRequestURI());
chain.doFilter(request, response);
});
registrationBean.addUrlPatterns("/foo/*");
return registrationBean;
}
}3.1 Key points
FilterRegistrationBeanand Filter have a one‑to‑one relationship.
When multiple FilterRegistrationBean instances exist, each must have a unique name via setName.
Execution order is controlled by setOrder(int order).
4. Summary
The article demonstrates two ways to use custom Servlet Filters in Spring Boot: a manual bean approach that offers deeper object‑oriented insight, and the built‑in FilterRegistrationBean mechanism that simplifies registration, ordering, and URL scoping.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
