java.net.http
JDK 11 でリリースされた新しいパッケージを使用しHttpRequest
て、意図的に低い応答タイムアウトでアセンブルされています。
HttpRequest.Builder builder = HttpRequest.newBuilder(getEndpointUri());
addRequestHeaders(builder);
builder.POST(HttpRequest.BodyPublishers.ofString(rawXml));
builder.timeout(Duration.ofMillis(1));
HttpRequest httpRequest = builder.build();
目的は、結果が正しく処理されることをテストすることHttpTimeoutException
ですが、予期せず、この応答タイムアウト値が につながり、HttpConnectionTimeoutException
このコードによってキャッチされています。
try {
HttpResponse<InputStream> httpResponse = completableExchange.join();
} catch (CompletionException ce) {
if (ce.getCause() instanceof HttpConnectTimeoutException) {
System.out.println("Connection timeout occurred!");
} else {
throw ce;
}
}
これは、応答タイムアウトにより、接続タイムアウトが発生したかのようにコードが動作することを意味します。私の理解では、接続タイムアウトと応答タイムアウトは別々の概念である必要があり、別々にキャッチして処理できるはずです。
に添付されたスタック トレースはHttpConnectionTimeoutException
次のようになります。
java.net.http.HttpConnectTimeoutException: HTTP connect timed out
at java.net.http/jdk.internal.net.http.ResponseTimerEvent.handle(ResponseTimerEvent.java:68)
at java.net.http/jdk.internal.net.http.HttpClientImpl.purgeTimeoutsAndReturnNextDeadline(HttpClientImpl.java:1248)
at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:877)
Caused by: java.net.ConnectException: HTTP connect timed out
at java.net.http/jdk.internal.net.http.ResponseTimerEvent.handle(ResponseTimerEvent.java:69)
... 2 more
タイムアウトの概念を誤解していますか? タイムアウト値は、デフォルトのタイムアウト値HttpRequest
の代替手段を提供するだけですか? HttpClient
接続と応答のタイムアウトを個別のイベントとしてキャッチする信頼できる方法はありますか?
価値があるのは、Javadoc forHttpRequest.Builder.timeout(Duration)
が次のように述べていることです。
このリクエストのタイムアウトを設定します。指定されたタイムアウト内に応答が受信されない場合、HttpTimeoutException が HttpClient::send からスローされるか、HttpClient::sendAsync が HttpTimeoutException で例外的に完了します。タイムアウトを設定しないことの効果は、無限の Duration を設定することと同じです。永久にブロックします。
ややこしいのは、技術的にはメソッドのコントラクトが満たされてHttpConnectionTimeoutException
いるサブクラスです。しかし、これは役に立たないようです。HttpTimeoutException
timeout(Duration)
(質問する前に: はい、渡された値は、例外がスローされるかどうかの決定要因です。したがって、例外は、インスタンスHttpRequest.Builder.timeout(Duration)
の作成に使用される接続タイムアウト値に基づいていません。)HttpClient