概要
WebClientにてHTTP通信時、リクエスト内容をログ出力させる方法についてまとめた。
ログ出力対象は、「HTTPメソッド」「URL」「ヘッダー」となる。
※「ボディ」は今回対象外
前提
WebClientのBean定義方法などについては以下を参照。
概要 RESTなAPIにアクセスするのはRestTemplateではなくWebClientが今後推奨となるため、WebClientの概要についてまとめた。 WebClientを使用するための準備と、どんなメソッドがあるのかを紹介している[…]
ExchangeFilterFunction
WebClientでは、通信の前後に処理を割り込ませる「フィルター機能」を提供している。
この「フィルター機能」を定義するためのインターフェースが、ExchangeFilterFunctionとなる。
今回はこのExchangeFilterFunctionを使って、HTTPリクエスト送信前にログ出力を行う処理を実装する。
基本的な使い方
ExchangeFilterFunctionにログ出力処理を定義して、WebClientのフィルターに登録する。
実装方法
ログ出力処理とWebClientのフィルター登録を行う。
ログ出力処理
ExchangeFilterFunctionにHTTPリクエスト送信前のログ出力処理を定義する。
WebClientConfig.java
private ExchangeFilterFunction logRequest() {
return ExchangeFilterFunction.ofRequestProcessor(req -> {
// リクエストメソッド、URLをログに出力
var sb = new StringBuilder();
sb.append("\n\n----------★★リクエストログ★★----------\n")
.append("★Request Method: ").append(req.method()).append("\n")
.append("★Request URI: ").append(req.url()).append("\n")
.append("★Request Headers:\n");
req.headers().forEach((name, values) -> values
.forEach(value -> sb.append(" ")
.append(name)
.append(": ")
.append(value)
.append("\n")));
logger.debug(sb.toString());
return Mono.just(req);
});
}
ExchangeFilterFunction.ofRequestProcessor()を使用することで、WebClientのHTTPリクエスト送信前の割り込み処理を定義できる。
引数にClientRequestを受け取って、ログ出力に必要な情報を参照する。
ClientRequest#methodを使用して、ログ出力用のStringBuilderにリクエスト時のHTTPメソッドを設定している。
ClientRequest#urlを使用して、ログ出力用のStringBuilderにリクエスト時のURLを設定している。
ClientRequest#headersを使用して、ログ出力用のStringBuilderにリクエスト時のヘッダー情報を設定している。
ログ出力する。
フィルター登録
DIコンテナで管理されているWebClientに対して、
リクエストログ出力を定義したExchangeFilterFunctionをフィルターとして登録する。
WebClientConfig.java
@Bean
public WebClient webClient(ReactorClientHttpConnector reactorClientHttpConnector) {
return WebClient.builder()
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE + ", " + MediaType.APPLICATION_PROBLEM_JSON_VALUE)
.clientConnector(reactorClientHttpConnector)
.filter(logRequest())
.build();
}
WebClientのfilter()に、定義したExchangeFilterFunctionを設定する。
これにより、WebClientを使用する際に共通処理として、HTTP通信前にリクエスト内容がログ出力される。
補足
ExchangeFilterFunction.ofRequestProcessor()にて参照するClientRequestについて補足する。
ClientRequestでは主に以下の情報を参照できる。
※ボディに関しては中身を参照できないため、ロギング処理内でリクエストボディをログ出力できない
種類 | 取得方法 | 備考 |
---|---|---|
HTTPメソッド | ClientRequest#method | HttpMethod型で取得 ⇒ ログ出力可能 |
URL | ClientRequest#url | java.net.URI型で取得 ⇒ ログ出力可能 |
ヘッダー | ClientRequest#headers | HttpHeaders型で全ヘッダーにアクセス可 ⇒ ログ出力可能 |
ボディ | ClientRequest#body | BodyInserter<?, ? super ClientHttpRequest>を返すだけで中身は参照できない ⇒ ログ出力不可能(※別途ボディの出力方法は紹介) |
動作確認
DIコンテナからWebClientを取得して、何らかのHTTP通信を行う。
動作確認用クラス
// GETリクエスト
ResponseEntity<Resource> resEntity = client
.getEntity(URI.create("http://localhost:8080/rest_prototype/rest01/1"), Resource.class);
// 動作確認
System.out.println("★★動作確認★★");
System.out.println("ステータス:" + resEntity.getStatusCode());
System.out.println("ヘッダー:" + resEntity.getHeaders());
System.out.println("ボディ:" + resEntity.getBody());
コンソール
----------★★リクエストログ★★----------
★Request Method: GET
★Request URI: http://localhost:8080/rest_prototype/rest01/1
★Request Headers:
Content-Type: application/json
Accept: application/json, application/problem+json
★★動作確認★★
ステータス:200 OK
ヘッダー:[Content-Type:"application/json;charset=UTF-8", Transfer-Encoding:"chunked", Date:"Thu, 26 Jun 2025 10:24:49 GMT"]
ボディ:Resource(id=1, name=りんご, hogeDate=2025-02-01)
★Request Method: GET
★Request URI: http://localhost:8080/rest_prototype/rest01/1
★Request Headers:…
リクエスト情報がログ出力された。
まとめ
☑ WebClientのリクエスト内容をログ出力するには、フィルター機能(ExchangeFilterFunction)を利用する
☑ ExchangeFilterFunction.ofRequestProcessor()を使うことで、リクエスト送信前に処理を割り込ませることができる
☑ このときClientRequestを使ってヘッダーやURIをログ出力できるが、リクエストボディの中身は参照できないので注意