1. 概要

このチュートリアルでは、機能的でリアクティブなWebフレームワークである SpringWebFluxWebClientフィルターについて説明します。

2. リクエストフィルター

フィルターは、クライアントの要求(または応答)をインターセプト、検査、および変更できます。ロジックは1つの場所にとどまるため、フィルターはすべての要求に機能を追加するのに非常に適しています。 ユースケースには、ほんの数例を挙げると、クライアントリクエストの監視、変更、ロギング、認証が含まれます。

リクエストには、0個以上のフィルターの順序付けられたチェーンがあります。

Spring Reactiveでは、フィルターは機能インターフェースExchangeFilterFunctionのインスタンスです。 フィルタ関数には、変更するClientRequestと次のExchangeFilterFunctionの2つのパラメータがあります。

通常、フィルター関数は、フィルターチェーン内の次の関数を呼び出すことによって戻ります。

ExchangeFilterFunction filterFunction = (clientRequest, nextFilter) -> {
    LOG.info("WebClient fitler executed");
    return nextFilter.exchange(clientRequest);
};

3. WebClientフィルタリング

リクエストフィルターを実装した後、それをWebClientインスタンスに「アタッチ」する必要があります。 これは、WebClientの作成中にのみ実行できます。

それでは、WebClientを作成する方法を見てみましょう。 最初のオプションは、ベースURLの有無にかかわらず WebClient.create()を呼び出すことです。

WebClient webClient = WebClient.create();

残念ながら、これではフィルターを追加できません。 したがって、2番目のオプションは私たちが探しているものです。

WebClient.builder()を使用して、フィルターを追加できます

WebClient webClient = WebClient.builder()
  .filter(filterFunction)
  .build();

4. カスタムフィルター

クライアントから送信されたHTTPGETリクエストをカウントするフィルターから始めましょう。

フィルタはリクエストメソッドを調べ、GETリクエストの場合は「グローバル」カウンタを増やします。

ExchangeFilterFunction countingFunction = (clientRequest, nextFilter) -> {
    HttpMethod httpMethod = clientRequest.method();
    if (httpMethod == HttpMethod.GET) {
        getCounter.incrementAndGet();
    }
    return nextFilter.exchange(clientRequest);
};

定義する2番目のフィルターは、リクエスト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は、 authenticationヘッダーをリクエストに追加するbasicAuthentication()フィルター関数を提供します。

結果として、そのためのフィルターを定義する必要はありません。

WebClient webClient = WebClient.builder()
  .filter(ExchangeFilterFunctions.basicAuthentication(user, password))
  .build();

6. 結論

この短い記事では、SpringでのWebFluxクライアントのフィルタリングについて説明しました。

いつものように、コード例はGitHubにあります。