1. Обзор
Использование фильтров широко распространено в веб-приложениях, так как они дают нам способ изменить запрос или ответ без изменения конечных точек.
В этом кратком учебнике мы опишем возможные способы их реализации с помощью WebFlux Framework.
Поскольку мы не будем подробно о самой базе WebFlux, вы можете проверить эту статью для более подробной информации.
2. Зависимость от Maven
Прежде всего, давайте объявим WebFlux Maven зависимость:
org.springframework.boot spring-boot-starter-webflux
3. Конечные точки
Сначала мы должны создать несколько конечных точек. По одному для каждого метода: на основе аннотации и функциональной основе.
Начнем с контроллера на основе аннотации:
@GetMapping(path = "/users/{name}") public MonogetName(@PathVariable String name) { return Mono.just(name); }
Для функциональной конечной точки мы должны сначала создать обработчик:
@Component public class PlayerHandler { public MonogetName(ServerRequest request) { Mono name = Mono.just(request.pathVariable("name")); return ok().body(name, String.class); } }
А также отображение конфигурации маршрутизатора:
@Bean public RouterFunctionroute(PlayerHandler playerHandler) { return RouterFunctions .route(GET("/players/{name}"), playerHandler::getName) .filter(new ExampleHandlerFilterFunction()); }
4. Типы фильтров WebFlux
Структура WebFlux предоставляет два типа фильтров: WebFilter s и ОбработчикFilterFunctions .
Основное различие между ними заключается в том, WebFilter реализации работают для всех конечных точек и ОбработчикFilterFunction реализации будут работать только для Маршрутизатор на основе них.
4.1. Вебфильтр
Мы реализуем WebFilter добавить новый заголовок в ответ. В результате, все ответы должны иметь такое поведение:
@Component public class ExampleWebFilter implements WebFilter { @Override public Monofilter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) { serverWebExchange.getResponse() .getHeaders().add("web-filter", "web-filter-test"); return webFilterChain.filter(serverWebExchange); } }
4.2. ОбработчикFilterFunction
Для этого мы реализуем логику, которая устанавливает статус HTTP для ЗАПРЕТНАЯ когда параметр “имя” равен “тесту”.
public class ExampleHandlerFilterFunction implements HandlerFilterFunction{ @Override public Mono filter(ServerRequest serverRequest, HandlerFunction handlerFunction) { if (serverRequest.pathVariable("name").equalsIgnoreCase("test")) { return ServerResponse.status(FORBIDDEN).build(); } return handlerFunction.handle(serverRequest); } }
5. Тестирование
В WebFlux Framework есть простой способ протестировать наши фильтры: WebTestClient . Это позволяет нам тестировать звонки HTTP в конечные точки.
Вот примеры конечной точки, основанной на аннотации:
@Test public void whenUserNameIsBaeldung_thenWebFilterIsApplied() { EntityExchangeResultresult = webTestClient.get() .uri("/users/baeldung") .exchange() .expectStatus().isOk() .expectBody(String.class) .returnResult(); assertEquals(result.getResponseBody(), "baeldung"); assertEquals( result.getResponseHeaders().getFirst("web-filter"), "web-filter-test"); } @Test public void whenUserNameIsTest_thenHandlerFilterFunctionIsNotApplied() { webTestClient.get().uri("/users/test") .exchange() .expectStatus().isOk(); }
А для функциональной конечной точки:
@Test public void whenPlayerNameIsBaeldung_thenWebFilterIsApplied() { EntityExchangeResultresult = webTestClient.get() .uri("/players/baeldung") .exchange() .expectStatus().isOk() .expectBody(String.class) .returnResult(); assertEquals(result.getResponseBody(), "baeldung"); assertEquals( result.getResponseHeaders().getFirst("web-filter"), "web-filter-test"); } @Test public void whenPlayerNameIsTest_thenHandlerFilterFunctionIsApplied() { webTestClient.get().uri("/players/test") .exchange() .expectStatus().isForbidden(); }
6. Заключение
Мы рассмотрели оба типа фильтров WebFlux в этом учебнике и рассмотрели некоторые примеры кода.
Для получения дополнительной информации о WebFlux Framework, посмотрите на документация .
Как всегда, полный исходный код для примеров можно найти более на GitHub .