Spring Boot
Filter Class
Java
Programming
Web Development

How can I add a filter class in Spring Boot?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Spring Boot, a filter is the right place for cross-cutting HTTP concerns such as logging, header checks, correlation IDs, or simple authentication rules. The usual pattern is to implement a servlet filter, then register it either as a bean or with a FilterRegistrationBean when you need URL patterns or explicit ordering.

The Simplest Option: Extend OncePerRequestFilter

For most applications, extending OncePerRequestFilter is easier than implementing the raw Filter interface because it already handles some servlet edge cases cleanly.

java
1import java.io.IOException;
2import jakarta.servlet.FilterChain;
3import jakarta.servlet.ServletException;
4import jakarta.servlet.http.HttpServletRequest;
5import jakarta.servlet.http.HttpServletResponse;
6import org.springframework.stereotype.Component;
7import org.springframework.web.filter.OncePerRequestFilter;
8
9@Component
10public class RequestLoggingFilter extends OncePerRequestFilter {
11
12    @Override
13    protected void doFilterInternal(
14        HttpServletRequest request,
15        HttpServletResponse response,
16        FilterChain filterChain
17    ) throws ServletException, IOException {
18
19        System.out.println("Request URI: " + request.getRequestURI());
20        filterChain.doFilter(request, response);
21    }
22}

Because the class is annotated with @Component, Spring Boot auto-detects it and adds it to the servlet filter chain.

Registering with FilterRegistrationBean

If you need more control, register the filter explicitly.

java
1import org.springframework.boot.web.servlet.FilterRegistrationBean;
2import org.springframework.context.annotation.Bean;
3import org.springframework.context.annotation.Configuration;
4
5@Configuration
6public class FilterConfig {
7
8    @Bean
9    public FilterRegistrationBean<RequestLoggingFilter> requestLoggingFilter() {
10        FilterRegistrationBean<RequestLoggingFilter> registration = new FilterRegistrationBean<>();
11        registration.setFilter(new RequestLoggingFilter());
12        registration.addUrlPatterns("/api/*");
13        registration.setOrder(1);
14        return registration;
15    }
16}

This is useful when:

  • the filter should apply only to certain URL patterns
  • the filter order matters
  • you do not want to rely on component scanning alone

A Header Validation Example

Filters are often used to reject requests before they reach controllers.

java
1import java.io.IOException;
2import jakarta.servlet.FilterChain;
3import jakarta.servlet.ServletException;
4import jakarta.servlet.http.HttpServletRequest;
5import jakarta.servlet.http.HttpServletResponse;
6import org.springframework.web.filter.OncePerRequestFilter;
7
8public class ApiKeyFilter extends OncePerRequestFilter {
9
10    @Override
11    protected void doFilterInternal(
12        HttpServletRequest request,
13        HttpServletResponse response,
14        FilterChain filterChain
15    ) throws ServletException, IOException {
16
17        String apiKey = request.getHeader("X-API-Key");
18
19        if (!"secret-key".equals(apiKey)) {
20            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
21            response.getWriter().write("Missing or invalid API key");
22            return;
23        }
24
25        filterChain.doFilter(request, response);
26    }
27}

Notice that the filter either ends the response early or calls filterChain.doFilter(...) to continue.

When to Use a Filter Versus Other Spring Features

A filter works at the servlet layer, before Spring MVC controller methods are invoked. That makes it a good fit for generic HTTP-level concerns.

Use a filter when you need:

  • request logging
  • header checks
  • correlation IDs
  • low-level request wrapping

Use controller advice, interceptors, or Spring Security when the concern is more framework-specific or authentication-heavy. Not every cross-cutting concern belongs in a filter.

Ordering Matters

If multiple filters exist, order determines who sees the request first. A logging filter may need to run before an authentication filter, or a correlation-ID filter may need to run very early so later logs can reuse that ID.

That is one reason FilterRegistrationBean is helpful in non-trivial applications.

Common Pitfalls

One common mistake is forgetting to call filterChain.doFilter(...) when the request should continue. If you leave that out, the request stops in the filter and never reaches the controller.

Another issue is doing too much application logic in the filter layer. Filters should stay focused on cross-cutting request and response concerns.

A third pitfall is using a filter when Spring Security already provides a better, more maintainable solution for the problem. That choice matters a lot in production systems.

Summary

  • In Spring Boot, filters are used for cross-cutting HTTP request and response handling.
  • 'OncePerRequestFilter is usually the easiest base class to extend.'
  • Use @Component for simple registration or FilterRegistrationBean for more control.
  • Always either continue with filterChain.doFilter(...) or end the response explicitly.
  • Keep filter logic focused on generic request-processing concerns.

Course illustration
Course illustration

All Rights Reserved.