How to Define a Spring Boot Filter?

How to Define a Spring Boot Filter? A Step-by-Step Guide with Examples

Spring Boot has become a go-to framework for building robust, scalable Java applications, thanks to its simplicity and powerful features. One of its key components is the ability to define filters, which allow developers to intercept and process HTTP requests and responses before they reach controllers or after they leave them. Filters are essential for tasks like logging, authentication, data transformation, and more.

In this blog post, we’ll explore how to define a Spring Boot filter, provide a working example, and discuss real-world use cases to help you implement filters effectively in your projects. Whether you’re a seasoned developer or just starting with Spring Boot, this guide will give you actionable insights. 


How to Define a Spring Boot Filter? A Step-by-Step Guide with Examples
How to Define a Spring Boot Filter? A Step-by-Step Guide with Examples


What is a Spring Boot Filter?

A filter in Spring Boot is a component that intercepts HTTP requests and responses in a web application. It operates at the servlet level, meaning it can process requests before they hit your controllers or modify responses before they’re sent back to the client. Filters are part of the Java Servlet API and are seamlessly integrated into Spring Boot.

Common use cases for filters include:

  • Logging request details (e.g., headers, IP addresses)
  • Authenticating and authorizing users
  • Modifying request/response data (e.g., adding headers)
  • Handling cross-cutting concerns like CORS or compression

Now, let’s dive into how to define a filter in Spring Boot.

Step-by-Step Guide to Define a Spring Boot Filter

Spring Boot provides multiple ways to create filters. The most common approach is to implement the javax.servlet.Filter interface and register it as a bean. Below, we’ll walk through the process with a practical example.

Step 1: Create a Custom Filter Class

Start by creating a class that implements the Filter interface. This interface requires you to override three methods: init, doFilter, and destroy.

Here’s an example of a custom filter that logs request details:


package com.example.demo.filter;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;

public class RequestLoggingFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(RequestLoggingFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // Initialization logic (if needed)
        logger.info("RequestLoggingFilter initialized");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();
        String method = httpRequest.getMethod();
        String remoteAddr = httpRequest.getRemoteAddr();

        logger.info("Incoming request: {} {} from IP: {}", method, requestURI, remoteAddr);

        // Pass the request down the filter chain
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // Cleanup logic (if needed)
        logger.info("RequestLoggingFilter destroyed");
    }
}

In this example:

  • init: Runs when the filter is initialized.
  • doFilter: Contains the core logic, logging the HTTP method, URI, and client IP.
  • destroy: Runs when the filter is removed or the application shuts down.

Step 2: Register the Filter in Spring Boot

To make the filter active, you need to register it. Spring Boot offers two main ways to do this:

Option 1: Using @Component (Simplest Approach)

Annotate your filter with @Component to let Spring Boot automatically register it. However, this approach applies the filter to all requests.


import org.springframework.stereotype.Component;

@Component
public class RequestLoggingFilter implements Filter {
    // Same code as above
}
Option 2: Using @Bean with FilterRegistrationBean (More Control)

For more control (e.g., specifying URL patterns or execution order), use a FilterRegistrationBean. Add this to a configuration class:


package com.example.demo.config;

import com.example.demo.filter.RequestLoggingFilter;
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 only to /api/* endpoints
        registrationBean.setOrder(1); // Set execution order (lower runs first)
        return registrationBean;
    }
}

Here, the filter applies only to URLs matching /api/* and has an execution order of 1.

Step 3: Test the Filter

Create a simple REST controller to test the filter:


package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class TestController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, Spring Boot!";
    }
}

Run your Spring Boot application and send a GET request to http://localhost:8080/api/hello. Check your logs—you should see something like:


INFO: Incoming request: GET /api/hello from IP: 127.0.0.1

Real-Time Use Cases for Spring Boot Filters

Filters are incredibly versatile. Here are some real-world scenarios where they shine:

  1. Authentication and Authorization
    • Use a filter to check JWT tokens or session data before allowing access to protected endpoints.
    • Example: Redirect unauthenticated users to a login page.
  2. Request Logging
    • Log request metadata (e.g., timestamps, headers, IPs) for debugging or auditing purposes, as shown in the example above.
  3. CORS Handling
    • Add a filter to set CORS headers (e.g., Access-Control-Allow-Origin) for cross-origin requests.
  4. Input Validation
    • Inspect and sanitize incoming request data to prevent security vulnerabilities like SQL injection.
  5. Performance Monitoring
    • Measure request processing time by recording timestamps in the filter.

Best Practices for Defining Filters in Spring Boot

  • Keep Filters Lightweight: Avoid heavy computations in doFilter to prevent performance bottlenecks.
  • Use Specific URL Patterns: With FilterRegistrationBean, target specific endpoints to avoid unnecessary filtering.
  • Handle Exceptions Gracefully: Wrap logic in try-catch blocks to ensure the filter chain continues even if an error occurs.
  • Order Matters: If you have multiple filters, set their setOrder values to control execution sequence.

Conclusion

Defining a filter in Spring Boot is straightforward yet powerful. By implementing the Filter interface and registering it appropriately, you can handle a wide range of cross-cutting concerns in your application. Whether you’re logging requests, securing endpoints, or customizing responses, filters give you fine-grained control over the HTTP lifecycle.

Try the example above in your next Spring Boot project, and experiment with real-time use cases that fit your needs. Got questions or a unique use case? Drop a comment below—I’d love to hear from you!

Post a Comment

Previous Post Next Post