π₯ “Filter vs Interceptor in Spring — Who’s the Real Gatekeeper?”
π The Hidden Guards of Your REST APIs (with Real Examples, Jokes & Weird Discoveries!)
π― 1) What Is Filter / Interceptor / OncePerRequestFilter?
π§Ή Filter
A Filter is a component from the Servlet API that sits at the very beginning of a request's journey. It is invoked before the Spring context even gets involved. It's great for tasks like CORS configuration, encoding setup, basic logging, and blocking or modifying raw requests/responses.
π€ Think of Filter as the club bouncer who checks everyone at the entrance—before they even see the dance floor!
π΅️ Interceptor
A HandlerInterceptor is a Spring MVC feature that works after the request has passed through the DispatcherServlet but before the controller method is executed. It can inspect the handler (controller) method, add attributes, or block the request if needed.
π€ It’s like the guy inside the club checking if you’re VIP before letting you in to the private room (controller logic). π
π§Ό OncePerRequestFilter
This is a special Spring class that extends Filter but ensures the filter logic is run only once per request, even if the request is forwarded or internally dispatched again (like /error
).
π OncePerRequestFilter is the chill bouncer that says “I’ve already checked this guy—no need to scan again.” π³
π ️ 2) When to Use Each Concept (With Examples)
π§ͺ Use Filter when:
You’re dealing with low-level request/response operations that must happen before Spring even touches the request.
π§Ύ Real-Time Example: CORS Header Filter
@Component
public class CorsHeaderFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
chain.doFilter(request, response);
}
}
π― Use this when your frontend (like React/Angular) is calling your backend from a different domain — browsers will block requests unless these headers are present.
π‘️ Another Real-Time Example: Security Headers Filter
@Component
public class SecurityHeadersFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("X-Content-Type-Options", "nosniff");
res.setHeader("X-Frame-Options", "DENY");
res.setHeader("X-XSS-Protection", "1; mode=block");
chain.doFilter(request, response);
}
}
π« Prevents clickjacking, XSS, and sneaky browser tricks.
π¦ Use cases: CORS, security headers, GZIP compression, request throttling, IP blocking, etc.
π Fun Fact: Filters run even when there's no controller mapped. They're the true bodyguards. πͺ
π Use OncePerRequestFilter when:
You want to filter requests in Spring but avoid multiple executions during internal dispatches.
π Example: JWT Token Validation
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String token = request.getHeader("Authorization");
// Validate token
chain.doFilter(request, response);
}
}
✨ Avoids double logging or duplicate security logic during error forwarding.
π‘ Why use it? Because twice is once too many.
π§ Use Interceptor when:
You need access to the controller method, parameters, or want to modify the model/view.
π Example: Logging controller methods using preHandle()
@Component
public class LoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (handler instanceof HandlerMethod method) {
System.out.println("Invoking: " + method.getMethod().getName());
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
response.setHeader("X-Custom-Header", "Intercepted");
}
}
π§ Use preHandle()
for logging or pre-checks, and postHandle()
for response customizations.
π― Best when you care about Spring MVC context — controller metadata, annotations, model attributes.
π¨ 3) Common Mistakes You Might Be Making π±
❌ Assuming Filters & Interceptors are interchangeable — they are NOT.
❌ Writing token validation in a regular Filter and wondering why it runs twice.
❌ Trying to access controller parameters in a Filter (spoiler: you can’t).
❌ Forgetting to add your Interceptor to the WebMvcConfigurer
.
π “I thought my logging was clean… until I saw every error logged twice. Once for the call, and once for the error page.”
𧬠4) Unknown Truths You Probably Didn't Know
π€― Bonus: Aren’t Filters, Interceptors, and OncePerRequestFilter All Just Called Once Per API?
Excellent question! It seems like all of them only run once per request… but here’s the plot twist π:
✅ Yes, normal Filters and Interceptors usually run once per request… BUT:
That’s only true when the request completes normally.
π§± If Spring internally forwards a request (like to /error
), a regular Filter runs again, causing duplicate logs or validations!
π§ͺ Imagine:
-
/api/data
fails → Spring forwards to/error
-
Your filter runs again for
/error
-
Logs twice, tokens rechecked, chaos! π΅π«
π‘ OncePerRequestFilter to the Rescue:
It marks the request as already filtered:
request.setAttribute("__once_per_request_filter_applied__", true);
So Spring skips it on internal forwards. Clean and safe.
π― Rule: If it must run once and only once, use
OncePerRequestFilter
.
π 5) Interview Questions and Answers — Spring Filter vs Interceptor vs OncePerRequestFilter
❓ Common Real-World Question: Can All Three (Filter, Interceptor, OncePerRequestFilter) Customize Request and Response?
✅ Short Answer: Yes — but not all in the same way or at the same point in the lifecycle!
π§ Deep Dive:
π§ Deep Dive: Comparison Table
Mechanism | Can Modify Request? | Can Modify Response? | When in Lifecycle? |
---|---|---|---|
Filter | ✅ Yes | ✅ Yes | Before DispatcherServlet |
OncePerRequestFilter | ✅ Yes | ✅ Yes | Same as Filter but once only |
Interceptor | ⚠️ Limited | ✅ Yes (postHandle) | After controller mapping |
π¬ Example Q: “How do you modify the response after the controller returns?”
π‘ A: Use postHandle()
of an Interceptor.
π¬ Example Q: “How do you inject CORS headers?”
π‘ A: Use a Filter (or OncePerRequestFilter).
π¬ Example Q: “How do you ensure the logic runs once even during /error?”
π‘ A: Use OncePerRequestFilter
.
π€ Never say “All 3 are same.” Say “Each has different superpowers.” π¦Έ
π Spring Request Flow Diagram — Filter vs Interceptor vs Controller
Let me break it into a diagrammatic sequence showing how and when each component runs:
π§ Explanation:
Component | Runs Before | Runs After | Can Access Controller? | Runs on /error forward? | Main Use |
---|---|---|---|---|---|
Filter | ✔️ | ✔️ | ❌ | ✔️ (yes) | CORS, Security, Logging |
OncePerRequestFilter | ✔️ (once) | ✔️ | ❌ | ❌ (no, once only) | Avoid double execution |
Interceptor | ✔️ | ✔️ | ✔️ (HandlerMethod) | ✔️ | Add attributes, Logging |
π€― When /error
or internal forwarding happens...
π§Ύ Labels :
-
✅ Filter → π¬ "Raw request modification — runs before Spring."
-
✅ OncePerRequestFilter → π§ "Like Filter, but only once per request."
-
✅ Interceptor → π§ͺ "Knows about controllers. You can check handler, annotations."
-
✅ DispatcherServlet → πͺ “Main gate to Spring MVC — routes to controllers.”
π§Ή 6) Wrapping Up — Final Thoughts π¬
Spring gives us all these tools for a reason. If you:
-
Want to control raw requests/responses π go with Filter or OncePerRequestFilter
-
Want to tweak stuff after controller logic π use Interceptor
π Just don’t mix them up or you’ll end up debugging “phantom filters” at 2 AM. π
π‘ “Filter = Bouncer. Interceptor = VIP checker. OncePerRequestFilter = Smart bouncer who remembers you.”
Have you faced filter madness or interceptor illusions in your project? π§♂️
Drop your stories or surprises below π — Let’s debug life together!
π’ Blog by Anandharaj — Sharing what I wish someone told me years ago. π
Comments
Post a Comment