1. Обзор
В этой статье мы сравним Java servlet Filter
и Spring MVC HandlerInterceptor ,
а также когда один из них может быть предпочтительнее другого.
2. Фильтровать
_
Фильтры являются частью веб-сервера, а не среды Spring. Для входящих запросов мы можем использовать фильтры, чтобы манипулировать и даже блокировать запросы от достижения любого сервлета . Наоборот, мы также можем заблокировать получение ответов от клиента.
Spring Security — отличный пример использования фильтров для аутентификации и авторизации. Чтобы настроить Spring Security, нам просто нужно добавить один фильтр, DelegatingFilterProxy
. Затем Spring Security может перехватывать весь входящий и исходящий трафик. Вот почему Spring Security можно использовать вне Spring MVC .
2.1. Создание фильтра
Чтобы создать фильтр, сначала мы создаем класс, реализующий интерфейс
javax.servlet.Filter
:
@Component
public class LogFilter implements Filter {
private Logger logger = LoggerFactory.getLogger(LogFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("Hello from: " + request.getLocalAddr());
chain.doFilter(request, response);
}
}
Затем мы переопределяем метод doFilter
, с помощью которого мы можем получить доступ или управлять объектами ServletRequest
, ServletResponse
или FilterChain
. Мы можем разрешать или блокировать запросы с помощью объекта FilterChain
.
Наконец, мы добавляем фильтр
в контекст Spring, аннотируя его с помощью @Component.
Весна сделает все остальное.
3. HandlerInterceptor
с
HandlerInterceptor
являются частью среды Spring MVC и находятся между DispatcherServlet и
нашими контроллерами
. Мы можем перехватывать запросы до того, как они достигнут наших контроллеров, а также до и после рендеринга представления.
3.1. Создание HandlerInterceptor
Чтобы создать HandlerInterceptor
, мы создаем класс, реализующий интерфейс org.springframework.web.servlet.HandlerInterceptor
. Это дает нам возможность переопределить три метода:
preHandle()
— выполняется перед вызовом целевого обработчика.postHandle ()
— выполняется после целевого обработчика, но до того, какDispatcherServlet
отобразит представлениеafterCompletion() —
Обратный вызов после завершения обработки запроса и рендеринга представления
Давайте добавим ведение журнала к трем методам в нашем тестовом перехватчике:
public class LogInterceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
logger.info("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.info("afterCompletion");
}
}
4. Ключевые отличия и варианты использования
Давайте посмотрим на диаграмму, показывающую, как фильтры Filter
и HandlerInterceptor
вписываются в поток запроса/ответа:
Фильтры перехватывают запросы до того, как они достигнут DispatcherServlet
, что делает их идеальными для таких крупномасштабных задач , как:
- Аутентификация
- Ведение журнала и аудит
- Сжатие изображений и данных
- Любая функциональность, которую мы хотим отделить от Spring MVC
HandlerIntercepor
s, с другой стороны, перехватывает запросы между DispatcherServlet
и нашими Controller
ами. Это делается в среде Spring MVC, предоставляя доступ к объектам Handler
и ModelAndView
. Это уменьшает дублирование и позволяет использовать более детализированные функции, такие как:
- Обработка сквозных задач, таких как ведение журнала приложений
- Подробные проверки авторизации
- Управление контекстом или моделью Spring
5. Вывод
В этой статье мы рассмотрели различия между Filter
и HandlerInterceptor
.
Ключевой вывод заключается в том, что с помощью Filter
мы можем манипулировать запросами до того, как они достигнут наших контроллеров и за пределами Spring MVC. В противном случае HandlerInterceptor
являются отличным местом для сквозных проблем, связанных с конкретным приложением. Предоставляя доступ к целевым объектам Handler
и ModelAndView
, мы получаем более детальный контроль.
Реализацию всех этих примеров и фрагментов кода можно найти на GitHub .