Подобно сервлетам, фильтры — это компоненты веб-приложения, которые можно привязать к веб-приложению. Но в отличие от других компонентов веб-приложений, фильтры «привязаны» к обработке контейнера. Это означает, что они могут получить доступ к запросу до того, как он достигнет сервлета, а также могут перехватить ответную информацию до того, как она будет возвращена клиенту. Этот доступ позволяет фильтрам проверять и изменять содержимое запросов и ответов.
Каковы методы интерфейса Filter?
в этом :
Инициализация фильтра вызывается, когда контейнер сервлета создает экземпляр фильтра, чтобы убедиться, что фильтр может работать правильно. Когда во время выполнения метода init() возникают следующие проблемы, веб-контейнер не настроит его так, чтобы он был доступен:
Бросить исключение сервлета
не вернулся в течение времени, установленного веб-контейнером
делатьФильтр :
Основной метод Filter используется для выполнения некоторых операций с множествами над каждым перехваченным запросом.
Типичные варианты использования следующие:
Перехватите HttpServletRequest клиента до того, как HttpServletRequest достигнет сервлета.
Осмотрите HTTPServletRequest по мере необходимости, а также измените заголовки и данные HTTPServletRequest.
Перехватите HttpServletResponse до того, как он достигнет клиента.
При необходимости проверьте HttpServletResponse, вы можете изменить заголовки и данные HttpServletResponse.
уничтожение:
Уничтожение фильтра вызывается, когда контейнер сервлета уничтожает экземпляр фильтра, чтобы освободить занятые им ресурсы. Этот метод будет вызываться веб-контейнером только после завершения или истечения времени ожидания всех потоков в методе doFilter().
Как реализовать собственный фильтр
Сначала нам нужно создать класс, реализующий интерфейс Filter, а затем переопределить методы в интерфейсе:
Затем создайте контроллер и укажите два пути запроса:
package com.demo.demofilter.demofilter.filter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("demoFilter")
public class FilterController {
@GetMapping("hello")
public String hello() {
System.out.println("接口被调用:hello() ");
return "hello filter";
}
@GetMapping("hi")
public String hi() {
System.out.println("接口被调用:hi()");
return "hi filter";
}
}
Запускаем проект, видим, что наш фильтр успешно инициализировался с запуском программы
Отправьте запросы на эти два интерфейса соответственно:
Наконец, остановите проект, тогда фильтр будет уничтожен.
Что такое связанный вызов фильтра?
Когда мы настраиваем несколько фильтров и запрос может быть перехвачен несколько раз, запрос будет следовать客户端 -> 过滤器1 -> 过滤器2 -> servlet -> 过滤器2 -> 过滤器1 -> 客户端Цепной поток, как показано ниже:
В приведенном выше примере кода, поскольку мы определяем фильтр только при выполненииfilterChain.doFilter(servletRequest, servletResponse);, запрос будет напрямую переадресован сервлету для вызова.
Так что нам нужно немного переделать его и посмотреть, что произойдет, когда мы добавим еще один DemoFilter2:
Видно, что когда запрос одновременно удовлетворяет условиям фильтрации нескольких фильтров,filterChain.doFilter()Он будет передан следующему фильтру в определенном порядке (который можно указать с помощью @Order), пока не попадет в сервлет для фактического вызова интерфейса. После завершения вызова ответ вернется по тому же пути и после повторного прохождения каждого фильтра наконец прибудет к клиенту.
Перехватчик Перехватчик
Что такое перехватчик?
Перехватчик — это стратегия реализации АОП, которая используется для перехвата метода или поля перед доступом к ним, а затем добавления некоторой операции до или после него. Как и фильтр, перехватчик также связан. Каждый вызов перехватчика выполняется в том порядке, в котором он объявлен. В целом перехватчики можно использовать следующими способами:
Ведение журнала: Журналы информации о запросах вероятности для мониторинга информации, статистики информации и т. Д.
Проверка разрешений: проверьте права доступа пользователя, аутентификацию или авторизацию и т. д.
Мониторинг производительности: запишите время начала и время окончания до и после входа в процессор через перехватчик, чтобы получить время обработки запроса.
Обычное поведение: прочитайте файл cookie, чтобы получить информацию о пользователе, и поместите объект пользователя в заголовок запроса, чтобы облегчить использование последующих процессов.
Каковы методы интерфейса перехватчика?
предварительный обработчик:
Метод предварительной обработки метода будет вызываться перед обработкой запроса. Обычно он используется для выполнения некоторых операций предварительной инициализации метода или для выполнения некоторой предварительной обработки текущего запроса; кроме того, его также можно использовать для суждений, таких как проверка разрешений, чтобы определить, следует ли продолжить выполнение запроса.
Этот метод возвращает логическое значение. Если значение равно false, запрос завершается, и последующие перехватчики и контроллеры не будут выполняться; если значение равно true, метод preHandler() следующего перехватчика будет продолжать вызываться. достигнут последний перехватчик, будет вызван Контроллер текущего запроса.
постобработчик:
Постобработка метода, который будет вызываться после обработки запроса. Хотя он выполняется после вызова метода Controller, его вызов все еще происходит до того, как DispatcherServlet визуализирует представление и возвращает его, поэтому обычно его можно использовать для работы с объектом ModelAndView, обрабатываемым контроллером.
после завершения:
Выполняется после завершения всей обработки запроса (включая отрисовку представления), в основном используется для очистки некоторых ресурсов.
Как реализовать собственный перехватчик
Аналогичным образом сначала создайте класс, реализующий интерфейс HandlerInterceptor, а затем переопределите методы интерфейса:
Далее вам необходимо зарегистрировать перехватчик, указав, какой перехватчик использовать, и URL-адрес, соответствующий перехватчику:
package com.demo.demofilter.demofilter.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 如果有多个拦截器,继续registry.add往下添加就可以啦
registry.addInterceptor(new DemoInterceptor()).addPathPatterns("/demoInterceptor/**");
}
}
Наконец, контроллер
package com.demo.demofilter.demofilter.interceptor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("demoInterceptor")
public class InterceptorController {
@GetMapping("hello")
public String hello() {
System.out.println("接口被调用:hello() ");
return "hello interceptor";
}
@GetMapping("hi")
public String hi() {
System.out.println("接口被调用:hi()");
return "hi interceptor";
}
}
Результаты приведены ниже:
Другие соображения
В процессе выполнения Http-запроса необходимы следующие шаги:
Запросы перехватываются DispatcherServlet
DispatcherServlet сопоставляет полученный URL-адрес с соответствующим контроллером.
Запрос обрабатывается перехватчиком до того, как запрос достигнет соответствующего контроллера.
После завершения обработки представление анализируется
вернуться к просмотру
Таким образом, только запросы, проходящие через DispatcherServlet, будут перехвачены перехватчиком, а наши пользовательские запросы Servlet не будут перехвачены.
Фильтры и перехватчики
Как типичная реализация идей АОП, фильтры имеют много общего и перехватчиков. И самая большая разница между ними заключается в следующем:Фильтры определены в спецификации сервлета, контейнер поддерживается сервлетом; пружинные перехватыватели в контейнере, поддерживаемом пружинной структурой.
Поэтому, как компонент Spring, перехватчиком можно управлять через IOC-контейнер, получать в нем каждый экземпляр bean-компонента и вызывать в spring различные ресурсы и объекты, такие как объекты Service, источники данных, управление транзакциями и т. д.; в то время как фильтровать нет.
В целом, два основных различия существуют в следующих аспектах:
Фильтры — это обратные вызовы на основе функций, а перехватчики основаны на механизмах отражения Java.
Фильтры могут изменить запрос, в то время как перехватчики не могут
Фильтр должен быть реализован в контейнере сервлета, а перехватчик может применяться к различным средам, таким как JavaEE, JavaSE и т. д.
Перехватчики могут вызывать различные зависимости в IOC-контейнере, в то время как фильтры не могут
Фильтры можно использовать только до и после запроса, а перехватчики можно детализировать для каждого метода.
Наконец, добавьте две картинки, хе-хе:
Фильтр, сервлет, время срабатывания перехватчика
Время срабатывания фильтра — после контейнера и до сервлета, поэтому триггер фильтраdoFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)Входным параметром является ServletRequest, а не HttpServletRequest, поскольку фильтр находится перед HttpServlet.
Отфильтровать шаги запуска перехватчика
На втором этапе механизм SpringMVC заключается в распределении запросов по разным контроллерам с помощью DispaterServlet, Фактически этот шаг выполняется в методе service() сервлета.