知識庫 / Spring WebFlux RSS 訂閱

Spring WebFlux 過濾器

Reactive,Spring WebFlux
HongKong
5
02:04 PM · Dec 06 ,2025

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 框架的更多信息,請參閲 文檔

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.