1. 概要

HTTP応答のステータスコードを使用して、特定の応答でアプリケーションが次に何をすべきかを判断すると役立つことがよくあります。

このチュートリアルでは、WebFluxのWebClient。を使用してRESTリクエストから返されるステータスコードと応答本文にアクセスする方法を見ていきます。

WebClientはSpring5で導入され、RESTfulサービスを呼び出す際の非同期I/Oに使用できます。

2. 使用事例

他のサービスにRESTful呼び出しを行う場合、アプリケーションは通常、返されたステータスコードを使用してさまざまな機能をトリガーします。 典型的なユースケースには、適切なエラー処理、リクエストの再試行のトリガー、ユーザーエラーの特定が含まれます。

そのため、REST呼び出しを行う場合、応答コードだけを取得するだけでは不十分なことがよくあります。 応答本体も必要な場合があります。

次の例では、RESTクライアントWebClientからの応答本文を解析する方法を見てみましょう。 動作を返されたステータスコードにリンクし、 WebClient によって提供されるステータスコード抽出の2つの方法を使用します:onStatusおよびExchangeFilterFunction。

3. onStatusを使用する

onStatus は、WebClient応答を処理するために使用できる組み込みのメカニズムです。 これにより、特定の応答(400、500、503など)またはステータスのカテゴリー(4XX、5XXなど)に基づいて、きめ細かい機能を適用できます。

WebClient
  .builder()
  .build()
  .post()
  .uri("/some-resource")
  .retrieve()
  .onStatus(
    HttpStatus.INTERNAL_SERVER_ERROR::equals,
    response -> response.bodyToMono(String.class).map(Exception::new))

onStatusメソッドには2つのパラメーターが必要です。 1つ目は、ステータスコードを受け取る述語です。 2番目のパラメーターの実行は、最初のパラメーターの出力に基づいています。 2つ目は、応答をMonoまたはException。にマップする関数です。

この場合、 INTERNAL_SERVER_ERROR (つまり、500)が表示された場合は、 bodyToMono、を使用して本文を取得し、それを新しいExceptionにマップします。 ]。

onStatus呼び出しをチェーンして、さまざまなステータス条件に機能を提供できるようにすることができます。

Mono<String> response = WebClient
  .builder()
  .build()
  .post()
  .uri("some-resource")
  .retrieve()
  .onStatus( 
    HttpStatus.INTERNAL_SERVER_ERROR::equals,
    response -> response.bodyToMono(String.class).map(CustomServerErrorException::new)) 
  .onStatus(
    HttpStatus.BAD_REQUEST::equals,
    response -> response.bodyToMono(String.class).map(CustomBadRequestException::new))
  ... 
  .bodyToMono(String.class);

// do something with response

これで、onStatus呼び出しがカスタム例外にマップされます。 2つのエラーステータスのそれぞれに例外タイプを定義しました。 onStatus メソッドを使用すると、選択した任意のタイプを使用できます。

4. ExchangeFilterFunctionの使用

アン ExchangeFilterFunction 特定のステータスコードを処理し、応答本文を取得する別の方法ですようではない onStatus 、交換フィルターは柔軟性があり、ブール式に基づくフィルター機能に適用されます。

ExchangeFilterFunction to は、onStatus関数と同じカテゴリをカバーするという柔軟性の恩恵を受けることができます。

まず、 ClientResponse で指定されたステータスコードに基づいて、返されたロジックを処理するメソッドを定義します。

private static Mono<ClientResponse> exchangeFilterResponseProcessor(ClientResponse response) {
    HttpStatus status = response.statusCode();
    if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
        return response.bodyToMono(String.class)
          .flatMap(body -> Mono.error(new CustomServerErrorException(body)));
    }
    if (HttpStatus.BAD_REQUEST.equals(status)) {
        return response.bodyToMono(String.class)
          .flatMap(body -> Mono.error(new CustomBadRequestException(body)));
    }
    return Mono.just(response);
}

次に、フィルターを定義し、ハンドラーへのメソッド参照を使用します。

ExchangeFilterFunction errorResponseFilter = ExchangeFilterFunction
  .ofResponseProcessor(WebClientStatusCodeHandler::exchangeFilterResponseProcessor);

onStatus 呼び出しと同様に、エラー時にExceptionタイプにマッピングしています。 ただし、 Mono.error を使用すると、この ExceptionReactiveExceptionにラップされます。このネストは、エラーを処理するときに注意する必要があります。

次に、これをWebClientのインスタンスに適用して、onStatus連鎖呼び出しと同じ効果を実現しましょう。

Mono<String> response = WebClient
  .builder()
  .filter(errorResponseFilter)
  .build()
  .post()
  .uri("some-resource")
  .retrieve()
  .bodyToMono(String.class);

// do something with response

5. 結論

この記事では、HTTPステータスヘッダーに基づいて応答本文を取得するためのいくつかの方法について説明しました。 ステータスコードに基づいて、 onStatus メソッドを使用すると、特定の機能をプラグインできます。 さらに、 filter メソッドを使用して、すべての応答の後処理を処理する汎用メソッドをプラグインできます。

いつものように、このチュートリアルのすべてのコードは、GitHubにあります。