2

java.net.httpJDK 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いるサブクラスです。しかし、これは役に立たないようです。HttpTimeoutExceptiontimeout(Duration)

(質問する前に: はい、渡された値は、例外がスローされるかどうかの決定要因です。したがって、例外は、インスタンスHttpRequest.Builder.timeout(Duration)の作成に使用される接続タイムアウト値に基づいていません。)HttpClient

4

1 に答える 1