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, andERRORdispatches 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:
OncePerRequestFilterdoes not run again for/final, butStandardFilterdoes.
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