Partner – Trifork – NPI (cat=Spring Boot)
announcement - icon

Navigating the complexities of Spring can be difficult, even for seasoned developers.

If you need direct, practical help and guidance with your own Spring work, Trifork's CTO, Joris Kuipers, is running a closed-door call.

It's free, but it's limited to only 3 seats, so if you need it, I would join quickly and be sure to attend:

>>> CTO Spring Open Office Hour Session - Technical Guidance

With more than 15 years of leading custom software development projects involving Spring, Joris has gained a lot of real-world experience, and this call is about sharing and helping the community.

Enjoy.

Course – LS – All

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE

 1. Overview

In this quick tutorial, we'll explore how to define custom filters and specify their invocation order with the help of Spring Boot.

Further reading:

Find the Registered Spring Security Filters

Learn how to find all the registered Spring Security filters in an application.

Configure a Spring Boot Web Application

Some of the more useful configs for a Spring Boot application.

2. Defining Filters and the Invocation Order

Let's start by creating two filters:

  1. TransactionFilter – to start and commit transactions
  2. RequestResponseLoggingFilter – to log requests and responses

In order to create a filter, we simply need to implement the Filter interface:

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

    @Override
    public void doFilter(
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {
 
        HttpServletRequest req = (HttpServletRequest) request;
        LOG.info(
          "Starting a transaction for req : {}", 
          req.getRequestURI());
 
        chain.doFilter(request, response);
        LOG.info(
          "Committing a transaction for req : {}", 
          req.getRequestURI());
    }

    // other methods 
}

@Component
@Order(2)
public class RequestResponseLoggingFilter implements Filter {

    @Override
    public void doFilter(
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {
 
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        LOG.info(
          "Logging Request  {} : {}", req.getMethod(), 
          req.getRequestURI());
        chain.doFilter(request, response);
        LOG.info(
          "Logging Response :{}", 
          res.getContentType());
    }

    // other methods
}

In order for Spring to recognize a filter, we need to define it as a bean with the @Component annotation.

Moreover, to have the filters fire in the right order, we need to use the @Order annotation.

2.1. Filter With URL Pattern

In the example above, our filters are registered by default for all of the URLs in our application. However, we may sometimes want a filter to only apply to certain URL patterns.

In this case, we have to remove the @Component annotation from the filter class definition and register the filter using a FilterRegistrationBean:

@Bean
public FilterRegistrationBean<RequestResponseLoggingFilter> loggingFilter(){
    FilterRegistrationBean<RequestResponseLoggingFilter> registrationBean 
      = new FilterRegistrationBean<>();
        
    registrationBean.setFilter(new RequestResponseLoggingFilter());
    registrationBean.addUrlPatterns("/users/*");
    registrationBean.setOrder(2);
        
    return registrationBean;    
}

Note, that in this case we need to explicitly set the order using a setOrder() method.

Now the filter will only apply for paths that match the /users/* pattern.

To set URL patterns for the filter, we can use the addUrlPatterns() or setUrlPatterns() methods.

3. A Quick Example

Now let's create a simple endpoint and send an HTTP request to it:

@RestController
@RequestMapping("/users")
public class UserController {
    
    @GetMapping()
    public List<User> getAllUsers() {
        // ...
    }
}

The application logs on hitting this API are :

23:54:38 INFO  com.spring.demo.TransactionFilter - Starting Transaction for req :/users
23:54:38 INFO  c.s.d.RequestResponseLoggingFilter - Logging Request  GET : /users
...
23:54:38 INFO  c.s.d.RequestResponseLoggingFilter - Logging Response :application/json;charset=UTF-8
23:54:38 INFO  com.spring.demo.TransactionFilter - Committing Transaction for req :/users

This confirms the filters are invoked in the desired order.

4. Conclusion

In this brief article, we summarized how to define custom filters in a Spring Boot webapp.

As always, the code snippets can be found over on GitHub.

Course – LS – All

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
4 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!