使用フレームワーク
Spring Framework 6 の WebClient
reactor-netty
なぜこの例外が発生するのか
Connection: close
は 「レスポンスを返したらサーバーが即座に接続を切る」という意味です。
そのため、HTTPクライアント側がまだレスポンスを読み取っている途中で接続が切られた場合、httpクライアントのライブラリは例外を発生します。
reactor-netty
は非同期・ノンブロッキングなので、まだレスポンス本文を全部受信していない状態で切断されるとPrematureCloseException
の例外をスローします。
PrematureCloseException
は、レスポンスの途中で接続が閉じられた(=完全にレスポンスを読み込む前に切断された)ことを示します。
解決策・対応方法
1. Connection: close を明示的に設定しない
通常、WebClient
/reactor-netty
は接続の管理を自動で行います。特別な理由がなければ、Connection: close
を指定しない方が安全です。
2. それでも Connection: close が必要な場合
どうしても Connection: close
を設定する必要がある場合は、以下のような方法で レスポンス本文が完全に読み込まれる前提で対処する必要があります:
WebClient client = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(
HttpClient.create()
.doOnRequest((req, conn) -> req.requestHeaders().set("Connection", "close"))
))
.build();
そのうえで、bodyToMono や bodyToFlux で 完全に読み込む処理を記述し、block() などで読み込みを完了させてください。
String response = client.get()
.uri("/some-endpoint")
.retrieve()
.bodyToMono(String.class)
.block(); // レスポンスを完全に読み込む