Filters и Interceptors
Два уровня перехвата запроса
Иногда одна и та же техническая логика нужна для множества endpoints: добавить request id, измерить время обработки, записать технический лог или проверить общий признак запроса. Копировать такой код в каждый controller не нужно. В web-приложении для этого часто используют Servlet Filter или Spring MVC HandlerInterceptor.
Filter работает на уровне Servlet
Filter находится раньше Spring MVC и видит запрос и ответ как Servlet-объекты. Он может выполнить код до продолжения цепочки и после её завершения.
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);
}
}
Filter подходит для логики, которой не обязательно знать, какой controller будет выбран. Он работает вокруг всей Servlet-цепочки.
Interceptor знает о Spring MVC handler
Interceptor включается уже внутри Spring MVC и может работать относительно найденного handler.
У HandlerInterceptor есть точки до вызова метода контроллера,
после его успешного выполнения и после завершения обработки запроса.
Поэтому выбор обычно зависит от уровня задачи: общая HTTP/Servlet-инфраструктура естественнее ложится в filter, а логика, которой важен именно MVC-handler, — в interceptor.