Filters и Interceptors

Базовый Spring
≈ 2 мин чтения

Два уровня перехвата запроса

Иногда одна и та же техническая логика нужна для множества 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.

Filter и interceptor не заменяют controller. Они нужны для сквозной инфраструктурной логики, а обработка конкретного endpoint должна оставаться в web-слое приложения.