제이온

[Spring] Что такое Filter, Interceptor и Argument Resolver?

  • Язык написания: Корейский
  • Страна: Все страныcountry-flag
  • ИТ

Создано: 2024-04-27

Создано: 2024-04-27 00:41

Что такое фильтр (Filter)?

Фильтр — это функция, определенная в стандартной спецификации J2EE, которая позволяет обрабатывать дополнительные задачи для всех запросов, соответствующих шаблону URL, до/после передачи запроса в диспетчерский сервлет (Dispatcher Servlet). Другими словами, управление осуществляется не контейнером Spring, а веб-контейнером, таким как Tomcat, поэтому обработка запроса происходит до достижения диспетчерского сервлета.


[Spring] Что такое Filter, Interceptor и Argument Resolver?


Реализация фильтра (Filter)

Для добавления фильтра необходимо реализовать интерфейс Filter из javax.servlet, который имеет следующие три метода.


  • Метод init
    • Это метод для инициализации объекта фильтра и добавления его в сервис. Веб-контейнер вызывает метод init один раз для инициализации объекта фильтра, после чего все последующие запросы обрабатываются с помощью метода doFilter().
  • Метод doFilter
    • Это метод, который выполняется веб-контейнером перед передачей всех HTTP-запросов, соответствующих url-pattern, в диспетчерский сервлет, и перед отправкой HTTP-ответа клиенту диспетчерским сервлетом.
      В качестве параметра doFilter() используется FilterChain, который позволяет передавать запрос следующему объекту назначения через вызов doFilter(). Вставив необходимый процесс обработки до/после chain.doFilter(), мы можем выполнить требуемую обработку.
  • Метод destroy
    • Это метод для удаления объекта фильтра из сервиса и возврата используемых ресурсов. Он вызывается веб-контейнером один раз, после чего он больше не обрабатывается методом doFilter().


Пример кода - Спецификация Servlet


Пример кода - @Component


  • @Component: Позволяет зарегистрировать Filter как bean Spring.
  • @Order: Позволяет определить порядок, если фильтров несколько.
  • Если фильтр, соответствующий спецификации Servlet, зарегистрирован таким образом как bean Spring, то можно использовать другие bean, соответствующие спецификации Spring.


Пример кода - @Configuration

Если вы хотите, чтобы фильтр работал только для определенного URI, вы можете зарегистрировать фильтр как bean Spring с помощью FilterRegistrationBean.


Назначение фильтра (Filter)

В основном отвечает за проверку и обработку самих параметров запроса.


  • Общие задачи, связанные с безопасностью
    • Поскольку фильтр работает в веб-контейнере, можно выполнять проверку безопасности (защита от XSS, CSRF и т. д.) и блокировать неверные запросы. Блокировка происходит до того, как запрос достигнет контейнера Spring, что повышает надежность.
  • Ведение журнала для всех запросов
  • Сжатие изображений/данных и кодировка строк
    • Фильтр реализует функции, часто используемые в веб-приложениях, такие как сжатие изображений или данных и кодировка строк.
  • Настройка ServletRequest
    • HttpServletRequest позволяет читать содержимое Body только один раз. Поэтому в Filter или Interceptor нельзя читать Body. Можно создать настраиваемый ServletRequest для ведения журнала Body.


Перехватчик (Interceptor)

Что такое перехватчик (Interceptor)?

В отличие от фильтра (Filter), который является стандартной спецификацией J2EE, перехватчик (Interceptor) — это технология, предоставляемая Spring, которая позволяет ссылаться на запрос и ответ до и после вызова диспетчерским сервлетом контроллера или обрабатывать их. Иными словами, в отличие от фильтра, который работает в веб-контейнере, перехватчик работает в контексте Spring.


Диспетчерский сервлет отправляет запрос на поиск соответствующего контроллера с помощью сопоставления обработчиков, в результате чего возвращается цепочка выполнения (HandlerExecutionChain). Таким образом, если в этой цепочке выполнения зарегистрирован один или несколько перехватчиков, они выполняются последовательно перед выполнением контроллера. Если перехватчиков нет, контроллер выполняется сразу.


Реализация перехватчика (Interceptor)

Для добавления перехватчика необходимо реализовать интерфейс org.springframework.web.servlet.HandlerInterceptor, который имеет следующие три метода.


  • Метод preHandle
    • Метод preHandle выполняется перед вызовом контроллера. Поэтому его можно использовать для выполнения предварительной обработки, обработки информации о запросе или добавления информации перед контроллером.
    • Третий параметр метода preHandle, параметр handler, представляет собой абстрактный объект, содержащий информацию о методе, к которому прикреплено @RequestMapping.
    • Тип возвращаемого значения метода preHandle — boolean. Если возвращаемое значение равно true, выполнение продолжается, в противном случае выполнение прерывается, и последующие действия (следующий перехватчик или контроллер) не выполняются.
  • Метод postHandle
    • Метод postHandle выполняется после вызова контроллера. Поэтому его можно использовать, если необходимо выполнить последующую обработку после контроллера.
  • Метод afterCompletion
    • Метод afterCompletion выполняется после завершения всех операций, включая генерацию окончательного результата во всех представлениях.


Пример кода


  • Созданный перехватчик регистрируется как bean.
  • Созданный перехватчик регистрируется в методе addInterceptors() интерфейса WebMvcConfigurer.
  • Перехватчики работают в порядке регистрации в InterceptorRegistry.


Назначение перехватчика (Interceptor)

В основном отвечает за обработку согласованности информации о запросе с использованием бизнес-логики.


  • Общие задачи, связанные с аутентификацией/авторизацией
    • Например, перед переходом к контроллеру можно проверить такие задачи, как аутентификация или авторизация, связанные с запросом клиента.
  • Ведение журнала вызовов API
    • С помощью получаемых объектов HttpServletRequest и HttpServletResponse можно записывать информацию о клиенте.
  • Обработка данных, передаваемых в контроллер
    • Полученные объекты HttpServletRequest и HttpServletResponse можно обработать и передать в контроллер.
  • Имитация AOP
    • Третий параметр метода preHandle, HandlerMethod, позволяет получить дополнительную информацию, такую как сигнатура выполняемого метода, и на основе этого определить, выполнять ли логику.


Фильтр (Filter) против перехватчика (Interceptor)

  • Фильтр выполняется в веб-контексте, а перехватчик — в контексте Spring, поэтому время выполнения различается.
  • Фильтр может обрабатывать действия до и после диспетчерского сервлета, а перехватчик — до и после контроллера.
  • Фильтр лучше использовать для задач, которые необходимо обрабатывать глобально независимо от Spring, для проверки самих входных параметров или в случае, когда вместо HttpServletRequest используется ServletRequest.
  • Перехватчик лучше использовать для глобальных задач, связанных с запросом клиента, поступающим в рамках Spring, или когда необходимо использовать бизнес-логику.
  • В перехватчике можно использовать @ControllerAdvice и @ExceptionHandler для обработки исключений, а в фильтре — нет.
    • Фильтр обычно обрабатывает исключения, возникающие в этот момент, путем помещения блока doFilter() в блок try~catch.


Разрешитель аргументов (Argument Resolver)

Что такое разрешитель аргументов (Argument Resolver)?

Разрешитель аргументов (Argument Resolver) может косвенно создавать нужный объект из значения, полученного при поступлении запроса в контроллер.


Назначение разрешителя аргументов (Argument Resolver)

Например, предположим, что запрос поступил вместе с токеном JWT. Нам нужно проверить, является ли этот токен действительным, а затем извлечь идентификатор, сохраненный в токене, и создать объект пользователя, который вошел в систему.

В этом случае, если не использовать Argument Resolver, необходимо реализовать процесс проверки токена и преобразования его в объект пользователя, вошедшего в систему, в каждом контроллере. Это приведет к появлению дублирующегося кода в контроллерах, в которых требуется проверка пользователя, и к увеличению ответственности контроллеров. Argument Resolver может решить эту проблему.


Реализация разрешителя аргументов (Argument Resolver)

ArgumentResolver можно использовать путем реализации HandlerMethodArgumentResolver. Этот интерфейс указывает на необходимость реализации двух следующих методов.



  • Метод supportsParameter
    • Создаем и прикрепляем определенную аннотацию перед параметром, для которого хотим выполнить ArgumentResolver. Метод supportsParameter() проверяет, прикреплена ли нужная аннотация к полученному методу, и если она присутствует, возвращает true.
  • Метод resolveArgument
    • Если в supportsParameter получено true, то есть если существует какой-либо метод с прикрепленной определенной аннотацией, этот метод связывает parameter с нужным форматом и возвращает его.


При использовании ArgumentResolver реализация контроллера будет выглядеть следующим образом.



Различия между разрешителем аргументов (Argument Resolver) и перехватчиком (Interceptor)

  • ArgumentResolver работает после перехватчика и возвращает нужный объект из значения, полученного при поступлении запроса в контроллер.
  • Перехватчик, наоборот, перехватывает запрос до фактического запуска контроллера и не может возвращать определенный объект. Существуют только типы возвращаемых значений boolean или void.


Источники


Ожидаемые вопросы на собеседовании и ответы

Что такое фильтр?

Фильтр — это функция, которая позволяет обрабатывать дополнительные задачи для всех запросов, соответствующих шаблону URL, до/после передачи запроса в диспетчерский сервлет, и работает на уровне контейнера сервлетов.


Когда следует использовать фильтр?

В фильтре можно обрабатывать задачи, которые необходимо выполнять глобально независимо от Spring. Или когда требуется проверка параметров запроса.

В основном он обрабатывает общие задачи, связанные с безопасностью, ведение журнала для всех запросов, сжатие изображений/данных и кодировку строк, настройку ServletRequest.


Что такое перехватчик?

Перехватчик — это функция, которая позволяет ссылаться на запрос и ответ до и после вызова диспетчерским сервлетом контроллера или обрабатывать их, и работает на уровне контейнера Spring.


Когда следует использовать перехватчик?

Перехватчик можно использовать для обработки задач, которые необходимо выполнять глобально, связанных с запросом клиента. Или когда требуется проверка, включающая вызов бизнес-логики.

В основном он обрабатывает общие задачи, связанные с аутентификацией/авторизацией, ведение журнала вызовов API, обработку данных, передаваемых в контроллер.


В чем разница между фильтром и перехватчиком?

Фильтр выполняется на уровне контейнера сервлетов, а перехватчик — на уровне контейнера Spring.

Фильтр может обрабатывать действия до и после диспетчерского сервлета, а перехватчик — до и после контроллера.

Поэтому фильтр лучше использовать для задач, которые необходимо выполнять глобально независимо от Spring, а перехватчик — для задач, связанных с запросом клиента, которые необходимо выполнять глобально.


Что такое разрешитель аргументов?

Разрешитель аргументов — это функция, которая косвенно создает нужный объект из значения, полученного при поступлении запроса в контроллер.


Когда следует использовать разрешитель аргументов?

Его можно использовать, когда запрос поступает вместе с токеном JWT, для проверки того, является ли этот токен действительным, а затем извлечения идентификатора, сохраненного в токене, и создания объекта LoginMember.


В чем разница между перехватчиком и разрешителем аргументов?

Разрешитель аргументов возвращает нужный объект из значения, полученного при поступлении запроса в контроллер. Перехватчик не может возвращать объекты, и он выполняется перед разрешителем аргументов.

Комментарии0

[Для неспециалистов, выживание разработчика] 14. Краткое изложение часто задаваемых вопросов на техническом собеседовании для начинающих разработчиковМы обобщили и систематизировали часто задаваемые технические вопросы на собеседовании для начинающих разработчиков (области памяти, структуры данных, базы данных и т. д.). Надеемся, что это поможет вам подготовиться к собеседованию по разработке.
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

April 3, 2024

Основные настройки nginx в качестве веб-сервераОписание способов оптимизации производительности веб-сервера nginx с помощью основных настроек (сжатие gzip, proxy_buffer, настройки worker/http, блок location). Рекомендуется применять после тестирования производительности.
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

September 26, 2024

DI на уровне фреймворка: под силу даже начинающим разработчикам Node.jsСтатья описывает реализацию внедрения зависимостей (DI) в разработке серверов Node.js. Рассматриваются способы реализации DI с использованием функции метаданных Reflect компилятора TypeScript, а также соответствующие библиотеки.
Sunrabbit
Sunrabbit
Sunrabbit
Sunrabbit

November 8, 2024

Как кэшировать ответы API + кэширование веб-страницСтатья о методах кэширования веб-страниц и ответов API. Рассматриваются различные методы кэширования с использованием хранилища браузера, Axios interceptor, фреймворка Nuxt, Nginx и другие, а также преимущества и недостатки кэширования на стороне сервера
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

September 29, 2024