BackendBench
Coffee

Unravel › Java concepts › APIs and web

Spring

Servlets, filters and interceptors

Every Java web request passes through the servlet layer.

🔎 Unravel this example

At a glance

Mental model

An airport: filters are the checks at the terminal entrance that everybody passes (security, tickets), interceptors are the gate agent just before boarding one flight, and the servlet or controller is the plane.

What happens, in order
  1. 1A Filter implements doFilter(request, response, chain)Do work before, call chain.doFilter(request, response) to continue, and optionally work after. Not calling the chain stops the request (for example answering 401).
  2. 2OncePerRequestFilter is the Spring base class that guarantees one execution per requestRegister filters as beans, with FilterRegistrationBean for ordering and URL patterns.
  3. 3A HandlerInterceptor has preHandle, postHandle and afterCompletion, and knows which controller method was selectedRegister it through WebMvcConfigurer.addInterceptors.
  4. 4HttpServletRequest carries headers, parameters, the session and the body streamHttpServletResponse is where status, headers and body are written.
Remember
Watch out
Reading the body in a filter and breaking the controllerForgetting to call chain.doFilter, so requests hang or return emptyKeeping per-request data in a field of a singleton filterLeaving a ThreadLocal set on pooled threads
Example (highlighted lines explain it)
public class RequestIdFilter extends OncePerRequestFilter {    @Override    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)            throws ServletException, IOException {        String id = request.getHeader("X-Request-Id");        if (id == null) id = UUID.randomUUID().toString();        response.setHeader("X-Request-Id", id);        chain.doFilter(request, response);    }}
  1. line 3 uses HttpServletRequest, the core of Servlets, filters and interceptors
  2. line 4 uses ServletException, the core of Servlets, filters and interceptors
Read the full explanation (about 2 min)

Every Java web request passes through the servlet layer. Filters wrap the whole request (before Spring sees it), interceptors wrap the controller call, and a servlet is the endpoint that finally answers.

A mental model

An airport: filters are the checks at the terminal entrance that everybody passes (security, tickets), interceptors are the gate agent just before boarding one flight, and the servlet or controller is the plane.

How it works

A Filter implements doFilter(request, response, chain). Do work before, call chain.doFilter(request, response) to continue, and optionally work after. Not calling the chain stops the request (for example answering 401).

OncePerRequestFilter is the Spring base class that guarantees one execution per request. Register filters as beans, with FilterRegistrationBean for ordering and URL patterns.

A HandlerInterceptor has preHandle, postHandle and afterCompletion, and knows which controller method was selected. Register it through WebMvcConfigurer.addInterceptors.

HttpServletRequest carries headers, parameters, the session and the body stream. HttpServletResponse is where status, headers and body are written.

Going deeper

The request body can be read only once. A logging filter that reads it must wrap the request (ContentCachingRequestWrapper), or the controller later sees an empty body.

Filters run for everything, including static files and errors, so cross-cutting concerns that need to be fast (correlation ids, authentication, CORS) belong here; concerns that need the controller (per-handler permissions) belong in interceptors.

Never store per-request data in filter fields: one filter instance serves all threads at once. Use request attributes or a ThreadLocal that you always clear in a finally block.

Under the hood

The servlet container (Tomcat) owns a worker thread per request. The filter chain is a linked list that the container builds per URL; chain.doFilter just calls the next one. DispatcherServlet is itself the last servlet in that chain, and interceptors run inside it.

Common mistakes

  • Reading the body in a filter and breaking the controller.
  • Forgetting to call chain.doFilter, so requests hang or return empty.
  • Keeping per-request data in a field of a singleton filter.
  • Leaving a ThreadLocal set on pooled threads.

How Unravel recognises it

When you paste code, Unravel looks for these signs of servlets, filters and interceptors. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Servlets, filters and interceptors?

Every Java web request passes through the servlet layer. Filters wrap the whole request (before Spring sees it), interceptors wrap the controller call, and a servlet is the endpoint that finally answers.

What are the most common mistakes with Servlets, filters and interceptors?

Reading the body in a filter and breaking the controller. Forgetting to call chain.doFilter, so requests hang or return empty. Keeping per-request data in a field of a singleton filter. Leaving a ThreadLocal set on pooled threads.

How can I see Servlets, filters and interceptors in real code?

Paste your own Java into Unravel and it will point out where servlets, filters and interceptors appears, explain how it works at the detail level you choose, and draw the flow of the code around it.