1. Обзор
В этом руководстве мы собираемся изучить фильтры WebClient в
Spring WebFlux
, функциональной реактивной веб-инфраструктуре.
2. Фильтры запроса
Фильтр может перехватывать, проверять и изменять клиентский запрос (или ответ). Фильтры очень подходят для добавления функциональности к каждому отдельному запросу, поскольку логика остается в одном месте. Варианты использования включают мониторинг, изменение, регистрацию и аутентификацию клиентских запросов, и это лишь некоторые из них.
Запрос имеет упорядоченную цепочку из нуля или более фильтров.
В Spring Reactive фильтры — это экземпляры функционального интерфейса ExchangeFilterFunction
. Функция фильтра имеет два параметра: ClientRequest
для изменения и следующий ExchangeFilterFunction
.
Обычно функция фильтра возвращается, вызывая следующую в цепочке фильтров:
ExchangeFilterFunction filterFunction = (clientRequest, nextFilter) -> {
LOG.info("WebClient fitler executed");
return nextFilter.exchange(clientRequest);
};
3. Фильтрация веб- клиента
После реализации фильтра запросов мы должны «прикрепить» его к экземпляру WebClient .
Это можно сделать только при создании WebClient
.
Итак, давайте посмотрим, как создать WebClient
. Первый вариант — вызвать WebClient.create()
с базовым URL-адресом или без него:
WebClient webClient = WebClient.create();
Это, к сожалению, не позволяет добавить фильтр. Второй вариант, значит, тот, который мы ищем.
Используя WebClient.builder()
, мы можем добавлять фильтры :
WebClient webClient = WebClient.builder()
.filter(filterFunction)
.build();
4. Пользовательский фильтр
Начнем с фильтра, который подсчитывает запросы HTTP GET, отправленные клиентом.
Фильтр проверяет метод запроса и увеличивает «глобальный» счетчик в случае запроса GET:
ExchangeFilterFunction countingFunction = (clientRequest, nextFilter) -> {
HttpMethod httpMethod = clientRequest.method();
if (httpMethod == HttpMethod.GET) {
getCounter.incrementAndGet();
}
return nextFilter.exchange(clientRequest);
};
Второй фильтр, который мы определим, добавляет номер версии к URL-пути запроса. Мы используем метод ClientRequest.from()
для создания нового объекта запроса из текущего и установки измененного URL-адреса.
Впоследствии мы продолжаем выполнять цепочку фильтров с новым измененным объектом запроса:
ExchangeFilterFunction urlModifyingFilter = (clientRequest, nextFilter) -> {
String oldUrl = clientRequest.url().toString();
URI newUrl = URI.create(oldUrl + "/" + version);
ClientRequest filteredRequest = ClientRequest.from(clientRequest)
.url(newUrl)
.build();
return nextFilter.exchange(filteredRequest);
};
Далее давайте определим фильтр для регистрации методов отправленных запросов вместе с их URL-адресами. Эти детали доступны в объекте запроса.
Все, что нам нужно сделать, это напечатать в некоторый выходной поток:
ExchangeFilterFunction loggingFilter = (clientRequest, nextFilter) -> {
printStream.print("Sending request " + clientRequest.method() + " " + clientRequest.url());
return nextFilter.exchange(clientRequest);
};
5. Стандартный фильтр
Наконец, давайте рассмотрим базовую аутентификацию — очень распространенный случай фильтрации запросов.
Вспомогательный класс ExchangeFilterFunctions
предлагает функцию фильтра basicAuthentication()
, которая добавляет в запрос заголовок авторизации .
В результате нам не нужно определять для него фильтр:
WebClient webClient = WebClient.builder()
.filter(ExchangeFilterFunctions.basicAuthentication(user, password))
.build();
6. Заключение
В этой короткой статье мы рассмотрели фильтрацию клиентов WebFlux в Spring.
Как всегда, пример кода можно найти на GitHub .