Sobes.tech
Назад к вопросам
Senior
4

Как реализовать параллельные HTTP-вызовы? Приходит запрос, нужно параллельно вызвать сервис по каждой задаче, дождаться всех ответов и вернуть результат.

Компании, где спрашивали
СБЕРСБЕР

Ответ от нейросети

sobes.tech AI

Для реализации параллельных HTTP-вызовов в Java можно использовать CompletableFuture из пакета java.util.concurrent. Идея в том, чтобы для каждой задачи запустить асинхронный HTTP-запрос, дождаться завершения всех с помощью CompletableFuture.allOf(), а затем собрать результаты.

Пример с использованием HttpClient из Java 11+:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

public class ParallelHttpCalls {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        List<String> urls = List.of(
            "https://service1/api/task",
            "https://service2/api/task",
            "https://service3/api/task"
        );

        List<CompletableFuture<HttpResponse<String>>> futures = urls.stream()
            .map(url -> {
                HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .GET()
                    .build();
                return client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
            })
            .collect(Collectors.toList());

        CompletableFuture<Void> allDone = CompletableFuture.allOf(
            futures.toArray(new CompletableFuture[0])
        );

        CompletableFuture<List<String>> allResponses = allDone.thenApply(v -> 
            futures.stream()
                .map(CompletableFuture::join)
                .map(HttpResponse::body)
                .collect(Collectors.toList())
        );

        List<String> results = allResponses.get();
        results.forEach(System.out::println);
    }
}

Таким образом, запросы выполняются параллельно, и мы ждем их завершения, прежде чем возвращать результат.