Filters and Interceptors

Basic Spring
≈ 2 min read

Two request interception levels

Sometimes the same technical logic is needed for many endpoints: adding a request id, measuring processing time, writing a technical log, or checking a common request property. There is no need to copy such code into every controller. In a web application, this is often handled with a Servlet Filter or a Spring MVC HandlerInterceptor.

A Filter works at the Servlet level

A Filter sits before Spring MVC and sees the request and response as Servlet objects. It can run code before continuing the chain and after the chain finishes.

class RequestIdFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        response.setHeader("X-Request-Id", UUID.randomUUID().toString());
        chain.doFilter(request, response);
    }
}

A Filter is suitable for logic that does not need to know which controller will be selected. It works around the entire Servlet chain.

An Interceptor knows about the Spring MVC handler

An Interceptor runs inside Spring MVC and can work relative to the resolved handler. HandlerInterceptor provides points before the controller method is invoked, after it completes successfully, and after request processing finishes.

So the choice usually depends on the task level: general HTTP/Servlet infrastructure fits more naturally in a Filter, while logic that specifically needs the MVC handler fits an Interceptor.

Filters and Interceptors do not replace controllers. They are intended for cross-cutting infrastructure logic, while processing a specific endpoint should remain in the application's web layer.