Spring WebFluxフィルタ

1.概要

フィルタは、エンドポイントを変更せずに要求や応答を変更する方法を提供するため、Webアプリケーションでは広く使用されています。

このクイックチュートリアルでは、それらをWebFluxフレームワークで実装するための考えられる方法について説明します。

WebFluxフレームワーク自体については詳しく説明しませんが、詳細については この記事 をチェックしてください。

2. Mavenの依存関係

まず最初に、WebFlux Mavenの依存関係を宣言しましょう。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

3.エンドポイント

最初にいくつかのエンドポイントを作成する必要があります。各メソッドに1つ

注釈ベースおよび機能ベース。

アノテーションベースのコントローラから始めましょう:

@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フレームワークは2種類のフィルタを提供します。

両者の主な違いは、 WebFilter 実装はすべてのエンドポイントで動作すること HandlerFilterFunction 実装は Router ベースの実装でのみ動作することです。

4.1. WebFilter

レスポンスに新しいヘッダを追加するために WebFilter を実装します。結果として、すべての応答は次のようになります。

@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フレームワークの詳細については、https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html[documentation]をご覧ください。

いつものように、例のための完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-5-reactive[GitHubで動く]で見つけることができます。