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.

Programmer DD
Programmer DD
Programmer DD
Master Custom Servlet Filters in Spring Boot: Scope, Order, and Registration

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

FilterRegistrationBean

and 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBackend DevelopmentSpring BootServlet FilterFilter Registration
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.