Java net HttpClient:对异步调用中的超时做出反应

Java net HttpClient: React to timeout in async call

我的目标是在 HttpClient 的 asyncronius 调用中对超时做出反应。我找到了很多关于如何设置不同超时的信息,但我没有找到任何关于如何应对超时的信息。

文档说明:

If the response is not received within the specified timeout then an HttpTimeoutException is thrown from HttpClient::send or HttpClient::sendAsync completes exceptionally with an HttpTimeoutException

但我不知道 exacly completes exceptionally 是什么意思。

例子

在同步调用中我可以做(如果测试后面的服务器URL不接听):

HttpRequest request = HttpRequest.newBuilder()
                                 .uri(new URI("http://localhost:8080/api/ping/public"))
                                 .timeout(Duration.ofSeconds(2))
                                 .build();
HttpClient client = HttpClient.newBuilder().build();

try {
  client.send(request, HttpResponse.BodyHandlers.ofInputStream());
} catch (HttpTimeoutException e) {
  System.out.println("Timeout");
}

我现在想要的是对异步调用做出相同的反应,例如:

HttpRequest request = HttpRequest.newBuilder()
                                 .uri(new URI("http://localhost:8080/api/ping/public"))
                                  .timeout(Duration.ofSeconds(2))
                                  .build();
HttpClient client = HttpClient.newBuilder().build();

client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).thenIfTimeout(System.out.println());

最后一次调用只是超时反应的占位符,并不存在。但是我该如何存档呢?

根据您尝试执行的操作,至少可以使用三种方法在发生异常时采取措施:

  1. CompletableFuture.exceptionally
  2. CompletableFuture.whenComplete
  3. CompletableFuture.handle
  • 1允许你在异常发生时return一个相同类型的结果
  • 2 允许您触发某些操作 - 并且不会更改完成 结果或异常。
  • 3 允许你触发一些动作,并改变完成的类型 结果或异常

到目前为止,最简单的方法是使用 2。类似于:

client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream())
      .whenComplete((r,x) -> {
            if (x instanceof HttpTimeoutException) {
                 // do something
            }
       });