java 30 lines · 6 steps

How a Spring HandlerInterceptor times requests

A Spring interceptor stamps each request with a start time and reports how long it took once the response completes.

Explained by highlit
1@Component
2public class RequestTimingInterceptor implements HandlerInterceptor {
3 
4 private static final Logger log = LoggerFactory.getLogger(RequestTimingInterceptor.class);
5 private static final String START_TIME = "requestStartTime";
6 private static final long SLOW_THRESHOLD_MS = 500;
7 
8 @Override
9 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
10 request.setAttribute(START_TIME, System.nanoTime());
11 return true;
12 }
13 
14 @Override
15 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
16 Long start = (Long) request.getAttribute(START_TIME);
17 if (start == null) {
18 return;
19 }
20 long elapsedMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
21 response.setHeader("X-Response-Time-Ms", Long.toString(elapsedMs));
22 
23 String endpoint = request.getMethod() + " " + request.getRequestURI();
24 if (elapsedMs >= SLOW_THRESHOLD_MS) {
25 log.warn("Slow request {} -> {} ({} ms)", endpoint, response.getStatus(), elapsedMs);
26 } else {
27 log.info("{} -> {} ({} ms)", endpoint, response.getStatus(), elapsedMs);
28 }
29 }
30}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Spring's HandlerInterceptor exposes preHandle and afterCompletion hooks that bracket the entire request lifecycle.
  2. 2Stashing state on the request attribute lets you carry data between the two hooks without shared mutable fields.
  3. 3afterCompletion always runs even on errors, making it the right place for cleanup and final measurements.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How a Spring HandlerInterceptor times requests — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code