1. 概述
使用過濾器在 Web 應用程序中非常普遍,因為它們允許我們在不修改端點的情況下修改請求或響應。
在本快速教程中,我們將描述使用 WebFlux 框架實現它們的一些方法。
由於我們將不深入介紹 WebFlux 框架本身,您可能想查看這篇文章以獲取更多詳細信息。
2. Maven 依賴
首先,聲明 WebFlux Maven 依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>3. 端點
首先我們需要創建一些端點。每個方法都需要一個端點:基於註解的以及基於功能的。
我們先從基於註解的控制器開始:
@GetMapping(path = "/users/{name}")
public Mono<String> getName(@PathVariable String name) {
return Mono.just(name);
}對於該功能端點,我們首先需要創建一個處理程序:
@Component
public class PlayerHandler {
public Mono<ServerResponse> getName(ServerRequest request) {
Mono<String> name = Mono.just(request.pathVariable("name"));
return ok().body(name, String.class);
}
}以下是路由器配置映射:
@Bean
public RouterFunction<ServerResponse> route(PlayerHandler playerHandler) {
return RouterFunctions
.route(GET("/players/{name}"), playerHandler::getName)
.filter(new ExampleHandlerFilterFunction());
}4. WebFlux 過濾器類型
WebFlux 框架提供了兩種類型的過濾器:<em >WebFilter</em> 和 <em >HandlerFilterFunction</em>。
主要的區別在於,<em >WebFilter</em> 實現適用於所有端點,而 <em >HandlerFilterFunction</em> 實現僅適用於基於 <em >Router</em> 的端點。
4.1. WebFilter
我們將實現一個 WebFilter 以向響應添加新的 HTTP 頭部。 結果,所有響應都應具有以下行為:
@Component
public class ExampleWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange,
WebFilterChain webFilterChain) {
serverWebExchange.getResponse()
.getHeaders().add("web-filter", "web-filter-test");
return webFilterChain.filter(serverWebExchange);
}
}4.2. HandlerFilterFunction
對於這個功能,我們實現了當“name”參數等於“test”時,將HTTP狀態碼設置為FORBIDDEN的邏輯。
public class ExampleHandlerFilterFunction
implements HandlerFilterFunction<ServerResponse, ServerResponse> {
@Override
public Mono<ServerResponse> filter(ServerRequest serverRequest,
HandlerFunction<ServerResponse> handlerFunction) {
if (serverRequest.pathVariable("name").equalsIgnoreCase("test")) {
return ServerResponse.status(FORBIDDEN).build();
}
return handlerFunction.handle(serverRequest);
}
}5. 測試
WebFlux 框架中,有便捷的方式來測試我們的過濾器:即 WebTestClient。它允許我們測試對我們端點的 HTTP 調用。
以下是一些基於註解的端點示例:
@Test
public void whenUserNameIsBaeldung_thenWebFilterIsApplied() {
EntityExchangeResult<String> result = 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() {
EntityExchangeResult<String> result = 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 框架的更多信息,請參閲 文檔。