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
实例的连接超时值。)