Как получить CompletableFuture‹T› из запроса асинхронного Http-клиента?

В документации по асинхронному Http-клиенту я вижу, как получить Future<Response> в результате асинхронного HTTP. Получить запрос, просто выполнив, например:

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> и использовать Обещание. Для этого я создал вспомогательный метод:

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> из запроса клиента Async Http?


person Miguel Gamboa    schedule 25.05.2016    source источник


Ответы (1)


С AHC2:

CompletableFuture<Response> f = asyncHttpClient
     .prepareGet("http://api.football-data.org/v1/soccerseasons/398")
     .execute()
     .toCompletableFuture();
person Stephane Landelle    schedule 25.05.2016
comment
Не могли бы вы включить CompletableFuture<T> пример использования в Readme.md репозитория AHC2? Я думаю, это полезно. - person Miguel Gamboa; 31.05.2016
comment
@StephaneLandelle В документации говорится: будьте осторожны, отмена этого CompletableFuture не приведет к правильной отмене текущего запроса. Есть очень хороший шанс, что мы вернем CompletionStage вместо этого в следующем выпуске. Хотите знать, есть ли в последней версии надлежащий CompletableFuture, который также будет корректно отменять запросы? - person user1571307; 06.08.2018