11

Async Http Client 文档中,我看到了如何通过Future<Response>简单的异步 HTTP Get 请求获取 a ,例如:

AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient();
Future<Response> f = asyncHttpClient
      .prepareGet("http://api.football-data.org/v1/soccerseasons/398")
      .execute();
Response r = f.get();

但是,为了方便起见,我想得到一个CompletableFuture<T>代替,为此我可以应用一个将结果转换为其他内容的延续,例如将响应内容从 Json 反序列化为 Java 对象(例如SoccerSeason.java)。这就是我想做的:

AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient();
CompletableFuture<Response> f = asyncHttpClient
     .prepareGet("http://api.football-data.org/v1/soccerseasons/398")
     .execute();
f
     .thenApply(r -> gson.fromJson(r.getResponseBody(), SoccerSeason.class))
     .thenAccept(System.out::println);

根据Async Http Client 文档,唯一的方法是通过一个AsyncCompletionHandler<T>对象并使用一个 Promise。所以我为此建立了一个辅助方法

CompletableFuture<Response> getDataAsync(String path){
    CompletableFuture<Response> promise = new CompletableFuture<>();
    asyncHttpClient
            .prepareGet(path)
            .execute(new AsyncCompletionHandler<Response>() {
                @Override
                public Response onCompleted(Response response) throws Exception {
                    promise.complete(response);
                    return response;
                }
                @Override
                public void onThrowable(Throwable t) {
                    promise.completeExceptionally(t);
                }
            });
    return promise;
}

使用这个实用方法,我可以重写前面的示例:

getDataAsync("http://api.football-data.org/v1/soccerseasons/398")
    .thenApply(r -> gson.fromJson(r.getResponseBody(), SoccerSeason.class))
    .thenAccept(System.out::println);

有没有更好的方法CompletableFuture<T>从异步 Http 客户端请求中获取?

4

1 回答 1

14

使用 AHC2:

CompletableFuture<Response> f = asyncHttpClient
     .prepareGet("http://api.football-data.org/v1/soccerseasons/398")
     .execute()
     .toCompletableFuture();
于 2016-05-25T12:47:24.643 回答