spring boot filter

In this post, we will learn how to add and configure filters in Spring Boot Application.

Why do we need Filter in Spring Boot?

When you are building an application you might come across different scenarios where you want to perform some check in the request before it hits your controller or your actual resource server. Let’s say for example authentication. Request has to be intercepted and credentials need to be verified before it is processed by our application for the response.

What is Filter in Spring?

Filter as the name suggest is an object that intercepts HTTP request, response or both. It performs filtering and process the request before the request can be handed over to controller and similarly, for response before the response is delivered to client. It is a part of webserver.

Spring boot provides options to create filter and register it in the spring boot application. Here in this post, we will be working with filter examples at both instances:

  • Request is processed before it is handed over to controller
  • Response sent back from controller is processed before it is delivered to client.

Add a Filter in Spring Boot

To add a filter you need to implement Filter interface. The following code is a typical outline for any Servlet filter. @Component annotation will tell Spring to register is as a Filter.

import javax.servlet.*;
import java.io.IOException;

@Component
public class ApiFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    }

    @Override
    public void destroy() {

    }
}

init() method is called when Filter is instantiated and destroy() method is called when application shuts down. During development we will be overriding doFilter() method only.

Register a Filter using OncePerRequestFilter

There is one more way to create Filter by extending OncePerRequestFilter.

@Component
public class ApiFilter extends OncePerRequestFilter {
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        
    }
}

This ensures that a specific filter is invoked only once per request. A common use case is while working with Spring Security and there is chain of filters. In such case we want the filter or authentication to be invoked only once. RequestDispatcher may forward the request to next servlet and the next servlet might have same filter which can cause multiple invocation of filter.

Logging Request/Response with Filter

Let’s override doFilter method.

@Component
public class ApiFilter implements Filter {

    private static final Logger LOG = (Logger) LoggerFactory.getLogger(ApiFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletRequest;

        LOG.info("Logging Request: " + req.getRequestURI());
        filterChain.doFilter(servletRequest, servletResponse);
        LOG.info("Logging Response : " + res.getStatus());
    }

    @Override
    public void destroy() {}
}

Anything before filterChain.doFilter() is executed before the request is sent to controller and anything after filterChain.doFilter() is to process or transform the response being sent back to client.

Spring Boot Filter Invocation Order

In real world, we might have multiple filters and in such scenario the order of filters how it is executed matters. So, if we have multiple filters then along with @Component annotation, we need to add @Order annotation as below.

@Component
@Order(1)
public class ApiFilterFirst implements Filter {

}
@Component
@Order(3)
public class ApiFilterSecond implements Filter {

}

In the above code, the order id determined by @Order annotation; lower the number, higher the precedence. ApiFilterFirst is executed first and the later next.

Register multiple filters by FilterRegistration Bean

In one use case, you might want certain request to only go through certain filter. Here we are filtering by URL.

One approach is by using FilterRegistrationBean. Every filter is registered here: urlpatters, order needs to be configured as needed. So, we do not need to set Order or Component annotation on to the Filter.

@Configuration
public class FilterRegistrationConfig {    

 @Bean    
  FilterRegistrationBean filterRegistration () {  
      FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();        
filterRegistrationBean.setFilter(new ApiFilter());    
    
filterRegistrationBean.setUrlPatterns(Arrays.asList("/api/books"));        

return filterRegistrationBean;    

}}

Conclusion

In this post, we dived into different ways to add a Filter into Spring Boot application. We also looked into ways to handle multiple filters and their invocation order. Now, you should be all set to work with Filter in your application.