Request Flow

  • Embedded Container (Tomcat) receives the request
  • It wraps request in a HttpServletRequest object
  • Filter chain is executed
  • Request is passed to the DispatcherServlet in Spring Boot’s MVC architecture.
  • Spring MVC HandlerInterceptors run before the controller (preHandle) and after the controller (postHandle and afterCompletion)
  • Then it delegates to appropriate Controller’s method
  • References
flowchart TD
    Client[Client]
    Container[Embedded Servlet Container - Tomcat/Jetty]
    Filters[Servlet Filter Chain]
    Dispatcher[DispatcherServlet]
    Interceptors[HandlerInterceptor]
    Controller[Controller / Handler]

    Client --> Container
    Container --> Filters
    Filters --> Dispatcher
    Dispatcher --> Interceptors
    Interceptors --> Controller

    Controller --> Interceptors
    Interceptors --> Dispatcher
    Dispatcher --> Filters
    Filters --> Container
    Container --> Client

DispatchServlet

  • It maps URLs to specific controller methods and coordinates the flow between other Spring components.
  • During application startup, Spring Boot scans all controllers (@Controller or @RestController) for mappings like @RequestMapping, @GetMapping, etc.
  • These mappings are stored in a HandlerMapping registry at runtime.

Filters

  • They intercept requests before reaching Spring DispatcherServlet
  • Pre-process request before controller
  • Post-process responses returned by the controller
  • Clean up after the request is fully completed.
  • Filter (Interface) > GenericFilterBean (Abstract) > OncePerRequestFilter (Abstract)
  • Invoke the next entity in the chain using the FilterChain object ( chain.doFilter() )
  • Keep the logic stateless and not depend on other requests
  • Use cases
    • Authentication: Validating user tokens
    • Rate Limiting: Preventing abuse by limiting requests
    • Logging: Recording request and response details
  • Reference
@Component
@Order(2) // tells order in filter chain
public class RequestResponseLoggingFilter implements Filter {
 
    @Override
    public void doFilter(
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) throws ServletException {
 
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        LOG.info(
          "Logging Request  {} : {}", req.getMethod(), 
          req.getRequestURI());
          
        // call doFilter to invoke next filter in the chain
        chain.doFilter(request, response);
 
        LOG.info("Logging Response :{}", res.getContentType());
    }
}

Interceptors

public class LoggerInterceptor implements HandlerInterceptor {
    
    boolean preHandle(...) {}
    
    void postHandle(...) {}
    
    void afterCompletion(...) {}
}
  • Should need to register using a @Configuration class
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
 
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoggerInterceptor())
  }
}

Error Handlers

Request Context