Partner – Orkes – NPI EA (cat=Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

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

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Accessibility testing is a crucial aspect to ensure that your application is usable for everyone and meets accessibility standards that are required in many countries.

By automating these tests, teams can quickly detect issues related to screen reader compatibility, keyboard navigation, color contrast, and other aspects that could pose a barrier to using the software effectively for people with disabilities.

Learn how to automate accessibility testing with Selenium and the LambdaTest cloud-based testing platform that lets developers and testers perform accessibility automation on over 3000+ real environments:

Automated Accessibility Testing With Selenium

1. Introduction

In this tutorial, the main focus will be to understand the purpose of the chain.doFilter() method in the Spring framework.

To gain a good understanding we’ll first explore what a filter is, what a filter chain is and what are some good use cases for utilizing filters. We’ll then discuss the purpose and importance of a chain.doFilter() method. Additionally, we’ll take a look at how to create our custom filters in Spring.

Finally, we’ll explore the correlation with one of the behavioral design patterns – Chain of Responsibility.

2. What Is a Filter in Spring?

In Spring applications, filters are based on Java Servlet Filters which represent objects that intercept requests and responses. Filters are part of the Java Servlet API and play an important role in web applications because they sit between the client and the server processing logic.

Using them, we can perform tasks before a request reaches the servlet or after a response is generated. Common use cases for filters include:

  • Authentication and Authorization
  • Auditing and Logging
  • Request/Response Modifications

Although not part of the Spring framework, filters are fully compatible with it. We can register them as Spring Beans and use them in our applications. Spring offers a few implementations of filters, some of the common ones include OncePerRequestFilter and CorsFilter.

3. Understanding the chain.doFilter() Method

Before we get into the chain.doFilter() method, it’s important to first understand the concept of the filter chain and its role in the filtering process.

A filter chain represents the sequential flow of processing logic applied to an incoming request or an outgoing response. In other words, it’s a collection of filters that are used to pre-process a request or post-process the response. The filters are arranged in a well-defined order, ensuring that each one can execute its processing logic before passing the request or response to the next stage in the chain.

To define a filter chain, we use the interface FilterChain from Java Servlet API, which contains our method of interest. If we examine the method’s signature, we can see that the request and response objects are defined as input parameters:

void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;

The chain.doFilter() method passes the request and response to the next filter in the chain. If no filters remain in the filter chain, a request is forwarded to the target resource, usually a servlet, and a response is sent to the client.

3.1. Why Is It Important to Call chain.doFilter()?

As we can see, the method chain.doFilter() plays an essential role as it ensures that the request continues through all filters in the chain. If we omit the method call, the request won’t proceed to the subsequent filters or the servlet. This could lead to unexpected application behavior, as any logic handled by the subsequent filters wouldn’t be reached.

On the other hand, in cases where authentication or authorization fails, it might benefit us to skip method invocation and break the chain.

4. The Chain of Responsibility Pattern

Now that we understand what chain.doFilter() enables us to do, let’s briefly look at its connection to the Chain of Responsibility pattern. We won’t go into much detail, rather we’ll describe what the pattern is and how it’s related to our topic.

The Chain of Responsibility pattern is a design pattern that focuses on interactions between objects. It explains how handlers, which are individual processing components, can be organized sequentially to process a request. Each handler performs a specific task and then decides whether to pass the request to the next handler for further processing.

If we compare pattern logic with servlet filters we’ll notice that filters are a real-world example of the Chain of Responsibility pattern. Each filter acts as a separate handler, responsible for a part of the processing logic.

The benefits of using this pattern include flexibility as we can add, remove, or reorder filters without modifying other components. Furthermore, the Chain of Responsibility pattern improves the separation of concerns by allowing filters to focus on a single task.

5. Implementing Custom Filters

Implementing custom filters is fairly simple, we’ll need to follow a few steps. In our example, let’s create two simple filters with log statements and showcase the chain.doFilter() method usage in practice.

5.1. Create Filter

First, we must implement a Filter interface and override the method doFilter().

An important thing to note is that this method isn’t the same as the doFilter() method inside the filter chain. The filter’s doFilter() method serves as the entry point where the specific processing logic for the filter should be implemented, while chain.doFilter() is used to pass the request and response to the next filter in the chain.

Here’s how we can implement filters and use the @Order annotation to arrange them:

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

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        LOG.info("Processing the First Filter");
        // Omit chain.doFilter() on purpose
    }
}

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

    @Override
    public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
        LOG.info("Processing the Second Filter");
        chain.doFilter(request, response);
    }
}

5.2. Method chain.doFilter() in Action

At this point, when executing any request in our application we can see that the response isn’t returned. The reason for that is that we broke the chain by omitting the chain.doFilter() invocation. If we observe the console, we’ll notice that the log from the second filter is missing:

11:02:35.253 [main] INFO  c.baeldung.chaindofilter.FirstFilter - Processing the First Filter

To restore the filter chain, we should include a method call in the first filter:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  throws IOException, ServletException {
    LOG.info("Processing the First Filter");
    chain.doFilter(request, response);
}

In this case, the first filter successfully passes the request and response to the second filter, and the filter chain has a continuous flow.

Let’s observe the console once again and confirm log statements are present:

11:02:59.330 [main] INFO  c.baeldung.chaindofilter.FirstFilter - Processing the First Filter
11:02:59.330 [main] INFO  c.baeldung.chaindofilter.SecondFilter - Processing the Second Filter

5.3. Register Filter

Notably, we annotated our filter with the @Component annotation to create a Spring Bean. This step is important because it allows us to register the filter in the servlet container.

There is another way to register filters, which offers more control and customization and it can be achieved by utilizing the FilterRegistrationBean class. Using that class we’re able to specify URL patterns and define the order of the filters.

6. Conclusion

In this article, we explored filters, the filter chain, and the correct use of the chain.doFilter() method. Also, we saw how to create and register our own custom filters in Spring.

Additionally, we discussed the connection to the Chain of Responsibility pattern and highlighted the flexibility and separation of concerns that filters provide.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Orkes – NPI EA (cat = Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

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

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)