Java 11 이상에서는 클라이언트 빌더에 ProxySelector를 설정합니다. JVM 전체의 프록시 속성은 건드리지 않습니다:

import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class ProxyExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newBuilder()
            .proxy(ProxySelector.of(
                new InetSocketAddress("203.0.113.10", 8080)))
            .connectTimeout(Duration.ofSeconds(5))
            .build();

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://example.com/"))
            .timeout(Duration.ofSeconds(15))
            .GET()
            .build();

        HttpResponse<String> response = client.send(
            request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode());
        System.out.println(response.body());
    }
}

문서용 예시 엔드포인트를 자신의 HTTP 프록시로 바꾸세요. HTTP 프록시 목록에서 시험할 후보를 찾을 수 있습니다. ProxySelector.of는 소켓 주소를 받습니다. 호스트에 http:// 접두사를 붙이지 말고 포트를 따로 전달하세요. HTTP 프록시를 선택하는 것이며, 포트 번호에 따라 SOCKS가 되는 것은 아닙니다. 요청 URI는 실제 목적지 그대로입니다.

HTTPS는 이 HTTP 프록시를 터널로 통과할 수 있습니다. 목적지를 다운그레이드할 필요가 없으며 이 설정이 프록시 리스너 자체의 TLS 지원을 뜻하지도 않습니다.

클라이언트 빌더의 연결 타임아웃은 연결을 맺을 때 적용되고, 요청에는 별도의 타임아웃이 있습니다. 요청이 기존 연결을 재사용할 수 있으므로 둘 다 명확히 두세요. 목적지 응답을 받기 전에 네트워크, 인증, 터널 예외가 생길 수 있지만, 오류 상태를 받았다고 반드시 예외가 발생하는 것은 아닙니다.

같은 라우팅 정책의 요청에는 클라이언트를 재사용해 앱이 연결 관리 기능의 이점을 얻도록 하세요.

관련 글