[java] HttpClient를 사용하여 웹 사이트에 동시에 요청을 보내고 응답을 확인하는 방법은?

Java에서 HttpClient를 사용하여 여러 웹 사이트에 동시에 요청을 보내고 응답을 확인하는 방법은 Java의 ExecutorService 및 CompletableFuture를 활용하는 것입니다. 이를 통해 비동기적으로 여러 요청을 처리하고 결과를 수신할 수 있습니다.

아래는 HttpClient를 사용하여 여러 웹 사이트에 동시에 요청을 보내고 응답을 확인하는 예제 코드입니다.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ConcurrentHttpRequestsExample {

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10); // 동시에 실행할 요청 수

        List<URI> uris = new ArrayList<>(); // 요청을 보낼 웹 사이트의 URI 리스트
        uris.add(URI.create("https://www.example1.com"));
        uris.add(URI.create("https://www.example2.com"));
        uris.add(URI.create("https://www.example3.com"));

        List<CompletableFuture<String>> responseFutures = new ArrayList<>(); // 응답을 저장할 CompletableFuture 리스트

        HttpClient httpClient = HttpClient.newHttpClient();

        for (URI uri : uris) {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(uri)
                    .build();

            CompletableFuture<String> responseFuture = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                    .thenApply(HttpResponse::body)
                    .exceptionally(e -> "Error occurred: " + e.getMessage());

            responseFutures.add(responseFuture);
        }

        CompletableFuture<Void> allResponsesFuture = CompletableFuture.allOf(
                responseFutures.toArray(new CompletableFuture[responseFutures.size()]));

        allResponsesFuture.thenAccept(v -> {
            for (CompletableFuture<String> responseFuture : responseFutures) {
                try {
                    String response = responseFuture.get();
                    System.out.println("Response received: " + response);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }

            executor.shutdown(); // ExecutorService 종료
        });

        try {
            allResponsesFuture.get(); // 모든 응답을 기다림
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

이 예제에서는 ExecutorService를 사용하여 요청을 동시에 처리하고, CompletableFuture를 사용하여 비동기적으로 응답을 받습니다. HttpClient의 sendAsync 메서드를 호출하여 비동기적으로 요청을 보내고, thenApply 메서드를 통해 응답을 가공합니다. exceptionally 메서드를 사용하여 예외가 발생한 경우 에러 메시지를 출력하도록 처리합니다.

모든 응답이 도착한 후 thenAccept 메서드에서 각 응답을 처리하고, ExecutorService를 종료합니다.

이 예제를 실행하면 각 웹 사이트로부터 동시에 요청이 보내지고, 응답이 받아진 후에 출력됩니다.

더 자세한 내용은 Java 11 Documentation을 참조하십시오.