2

java.net.http使用与 JDK 11 一起发布的新包,HttpRequest已将 an 组装成故意低响应超时:

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)说明如下:

为此请求设置超时。如果在指定的超时时间内未收到响应,则从 HttpClient::send 抛出 HttpTimeoutException 或 HttpClient::sendAsync 异常完成并出现 HttpTimeoutException。不设置超时的效果和设置一个无限的Duration是一样的,即。永远封锁。

让事情变得混乱的是,从技术上讲,HttpConnectionTimeoutException它是一个子类,HttpTimeoutException该方法的合同timeout(Duration)正在被满足。但这似乎无济于事。

(在你问之前:是的,传递给的值HttpRequest.Builder.timeout(Duration)是是否抛出异常的决定因素。所以异常不是基于用于创建HttpClient实例的连接超时值。)

4

1 回答 1

3

IIRC 如果在引发超时时连接未连接,或者在连接完成连接之前引发连接超时,您将收到 HttpConnectionTimeoutException。

发送请求时 - 底层连接可能已连接或未连接 - 取决于是否在池中找到合适的现有连接。请求超时立即开始 - 与底层连接的状态无关。如果底层连接尚未连接,并且请求超时在连接之前到期,那么您将收到 HttpConnectionTimeoutException,因为在为响应传递的请求分配的时间内无法连接连接。您可以将其视为请求超时剪辑连接超时。

您是否有任何特定的用例来区分这两种情况:

  1. 引发 HttpConnectionTimeoutException 是因为在连接超时指定的时间内无法连接连接,
  2. 引发 HttpConnectionTimeoutException 是因为在连接可以连接之前请求超时已过期?
于 2019-01-17T13:00:32.653 回答