Understanding Spring Boot Filters

I am a backend developer, interested in writing about backend engineering, DevOps and tooling.
Introduction
In a Spring Boot application, filters are powerful tools that allow you to intercept and manipulate HTTP requests and responses before they reach the controller layer. Filters are typically used to perform cross-cutting concerns such as logging, authentication, input validation, or modifying request and response data. They provide a flexible and centralized way to handle these concerns for multiple endpoints without duplicating code in every controller. In this article, we will explore what filters are, the advantages they offer, and how to implement them in a Spring Boot application.
Advantages of Using Filters
Separation of Concerns: Filters allow for cross-cutting functionality to be centralized, keeping business logic separate and reducing code duplication across controllers.
Pre-Processing and Post-Processing: Filters give you the ability to handle requests and responses before they are processed by a controller or after the controller has generated a response.
Security: Filters are commonly used for authentication and authorization, verifying user identity and roles before a request is allowed to proceed.
Logging and Monitoring: Filters can be used to log incoming requests, outgoing responses, and their execution times, helping to monitor and debug the application.
Performance Optimization: By filtering unnecessary requests or responses before they hit the controller, filters can improve the overall performance of the application.
Code Example
In this section, we’ll demonstrate how to create and use filters in a Spring Boot application to log requests and validate input.
Logging Filter Example
Creating a Filter Class
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class RequestLoggingFilter extends HttpFilter {
private static final Logger logger = LoggerFactory.getLogger(RequestLoggingFilter.class);
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("Incoming request: {} {}", request.getMethod(), request.getRequestURI());
chain.doFilter(request, response);
logger.info("Outgoing response status: {}", response.getStatus());
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
logger.info("Initializing RequestLoggingFilter");
super.init(filterConfig);
}
@Override
public void destroy() {
logger.info("Destroying RequestLoggingFilter");
super.destroy();
}
}
Explanation:
This
RequestLoggingFilterlogs the HTTP method, request URI, and response status.It overrides the
doFiltermethod to add logging functionality before and after the request is processed by the controller.The
initanddestroymethods can be overridden for setup and cleanup when the filter is initialized and destroyed.
Input Validation Filter Example
Creating an Input Validation Filter
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@Component
public class InputValidationFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String param = request.getParameter("input");
if (param == null || param.isEmpty()) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
response.getWriter().write("Missing or invalid input parameter");
return;
}
chain.doFilter(request, response); // Proceed to the next filter or controller
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
super.init(filterConfig);
}
@Override
public void destroy() {
super.destroy();
}
}
Explanation:
This filter checks if an
inputparameter is present in the HTTP request. If it’s missing or empty, the filter responds with a400 Bad Requeststatus and a custom error message.If the validation passes, the filter calls
chain.doFilterto continue processing the request.
Registering Filters in Spring Boot
You can register filters in a Spring Boot application either by annotating the filter class with @Component (as shown above) or by using a FilterRegistrationBean in the configuration class.
Using FilterRegistrationBean:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<RequestLoggingFilter> loggingFilter() {
FilterRegistrationBean<RequestLoggingFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new RequestLoggingFilter());
registrationBean.addUrlPatterns("/api/*"); // Apply filter to specific URL patterns
return registrationBean;
}
}
Explanation:
The
FilterRegistrationBeanallows you to configure filters programmatically.You can set the URL patterns where the filter should apply, rather than applying it globally to all requests.
Conclusion
Filters in Spring Boot provide a flexible and powerful mechanism for handling cross-cutting concerns such as logging, security, and input validation. By using filters, you can easily intercept requests and responses, applying logic before or after they reach the controller. Whether you're building a simple logging mechanism or complex authentication checks, filters help to keep your application clean, modular, and maintainable. Integrating filters is straightforward, and Spring Boot provides multiple options to configure them based on your needs.




