Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Filter versus HandlerInterceptor: choose the right request boundary

Last updated: 1 Oct 20265 min read
tutorial
IntermediateBy AITrove Editorial

A Servlet Filter runs in the container chain around a servlet. A HandlerInterceptor runs after Spring MVC has selected a handler. That ordering decides which failures and responses each mechanism can observe.

Use the earliest boundary that owns the rule

Authentication and authorization belong in the Spring Security filter chain, where they can apply before MVC and use its established request matching. Interceptors suit handler-aware behavior such as recording which controller processed an accepted request. A global correlation identifier can live in a filter, including for requests that never reach a controller.

Java
package in.aitrove.receipts;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

@Component
class RequestIdentifierFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain)
            throws ServletException, IOException {
        String requestId = UUID.randomUUID().toString();
        request.setAttribute("requestId", requestId);
        response.setHeader("X-Request-Id", requestId);
        chain.doFilter(request, response);
    }
}

The filter deliberately generates its own ID rather than trusting an arbitrary client header as evidence of identity. The ID is diagnostic only. It does not authenticate a user or bind a tenant. For asynchronous or error dispatches, check the filter dispatch policy and test the response path your server actually uses.

OncePerRequestFilter controls invocation within its dispatch policy; it is not a promise that a browser action triggers only one HTTP request. UUID generation is bounded work per request. Logging every request body would add memory, disk and privacy cost that this filter does not need.

Common Mistakes

  • Enforcing authorization only in a HandlerInterceptor and assuming every servlet path reaches MVC.
  • Registering one filter twice and misdiagnosing repeated work as a controller problem.
  • Using a client-supplied request ID as trusted authorization context.

Read next

MVC request processing, the security filter chain, and health endpoint exposure.

spring
spring-boot
filters-vs-interceptors
Storage details