When building Spring Boot applications, intercepting HTTP requests is a common requirement — for authentication, logging, or preprocessing. Two tools often used for this purpose are:
-
Filter
(from the Servlet API) -
OncePerRequestFilter
(provided by Spring)
They may seem interchangeable, but they behave very differently in real-world scenarios. This blog will guide you through their differences, show how chain.doFilter()
works, and provide a live example.
What is a Filter?
A Filter
is part of the Java Servlet API (jakarta.servlet.Filter
). It allows you to intercept requests before they hit your controller.
🔍 Key Points:
-
Can execute multiple times for the same logical request
-
Executes for all types of dispatches:
REQUEST
,FORWARD
,INCLUDE
,ERROR
-
Ideal for generic request modifications or logging at the servlet container level
What is OncePerRequestFilter
?
OncePerRequestFilter
is a Spring Framework utility (org.springframework.web.filter.OncePerRequestFilter
) that ensures the filter logic is invoked only once per request lifecycle, even if the request is forwarded or included.
🔍 Key Points:
-
Executes only once per request
-
Ignores
FORWARD
,INCLUDE
, andERROR
dispatches by default -
Best suited for authentication, JWT validation, rate limiting
What Does chain.doFilter()
Do?
Within any filter, the line:
means:
“Pass control to the next filter in the chain or ultimately to the controller if no filters remain.”
If you don’t call chain.doFilter()
, the request will not proceed any further. You can short-circuit the request (e.g., return 401 Unauthorized).
Let's See the Difference in Action
We’ll build a Spring Boot setup with:
-
A standard
Filter
-
A
OncePerRequestFilter
-
A controller that forwards one endpoint to another
1. StandardFilter.java
2. CustomOnceFilter.java
3. DemoController.java
Output When Accessing /entry
☝️ Notice:
OncePerRequestFilter
does not run again for/final
, butStandardFilter
does.
Comparison Table
Feature | Filter | OncePerRequestFilter |
---|---|---|
API Source | Servlet API (jakarta.servlet ) | Spring Web (org.springframework ) |
Runs for FORWARD/INCLUDE | ✅ Yes | ❌ No |
Executes only once per request | ❌ No | ✅ Yes |
Best for | Low-level container tasks | App-level logic (auth, JWT, etc.) |
Requires extra config? | ❌ No | ❌ No |
When Should You Use Each?
Use Case | Recommended Filter Type |
---|---|
Simple logging for all requests | Filter |
Authentication, JWT validation | OncePerRequestFilter |
Rate limiting or custom headers | OncePerRequestFilter |
Static resource filtering | Filter |
Final Recommendation
If you're building Spring Boot REST APIs and want to add logic like token validation, logging, or rate-limiting — go for OncePerRequestFilter
. It's Spring-friendly, clean, and avoids surprises like multiple executions during forwards.
Only use the plain Filter
when dealing with servlet-level tasks or need fine-grained control over dispatch types.
0 Comments