Class HttpClient
Class HttpClient
public abstract class HttpClient
extends Object
implements AutoCloseable
HTTP 클라이언트예요. HttpClient는 요청을 보내고 그 응답을 가져오는 데 사용될 수 있어요. HttpClient는 빌더를 통해 만들어져요. newBuilder 메서드는 기본 HttpClient 구현의 인스턴스를 만드는 빌더를 반환해요. 그 빌더는 클라이언트별 상태를 구성하는 데 사용될 수 있어요. 예를 들어:
- 선호하는 프로토콜 버전(HTTP/1.1 또는 HTTP/2)
- 리다이렉트를 따를지 여부
- 프록시
- 인증자(authenticator)
등이에요. 한 번 빌드되면 HttpClient는 불변(immutable)이며 여러 요청을 보내는 데 사용될 수 있어요. HttpClient는 그를 통해 보내지는 모든 요청에 구성 정보와 리소스 공유를 제공해요. HttpClient 인스턴스는 일반적으로 자체 연결 풀을 관리하며, 필요할 때마다 이를 재사용할 수 있어요. 연결 풀은 일반적으로 HttpClient 인스턴스 간에 공유되지 않아요. 각 연산마다 새 클라이언트를 만드는 것은 가능하지만, 보통 그러한 연결의 재사용을 막게 돼요. 보내지는 각 HttpRequest마다 BodyHandler가 제공되어야 해요. BodyHandler는 응답 본문이 있으면 그것을 어떻게 처리할지 결정해요. HttpResponse를 받으면 헤더, 응답 코드, (보통) 본문을 사용할 수 있게 돼요. 응답 본문 바이트가 읽혔는지 여부는 응답 본문의 타입 T에 따라 달라져요.
요청은 동기적 또는 비동기적으로 보낼 수 있어요.
send(HttpRequest, BodyHandler)는 요청이 보내지고 응답이 받아질 때까지 블록해요.sendAsync(HttpRequest, BodyHandler)는 요청을 보내고 응답을 비동기적으로 받아요.sendAsync메서드는CompletableFuture<HttpResponse>로 즉시 반환해요.CompletableFuture는 응답이 사용 가능해지면 완료돼요. 반환된CompletableFuture는 여러 비동기 작업 간의 의존성을 선언하기 위해 다양한 방식으로 결합될 수 있어요.
동기적 예시
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.followRedirects(Redirect.NORMAL)
.connectTimeout(Duration.ofSeconds(20))
.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
.authenticator(Authenticator.getDefault())
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
HttpClient
protected HttpClient()
HttpClient를 만들어요.
newHttpClient
public static HttpClient newHttpClient()
기본 설정으로 새 HttpClient를 반환해요. newBuilder().build()와 동등해요. 기본 설정은 다음을 포함해요: "GET" 요청 메서드, HTTP/2 선호, NEVER 리다이렉션 정책, 기본 프록시 선택기, 기본 SSL 컨텍스트.
- Implementation Note: 시스템 전체 기본 값은
HttpClient인스턴스가 구성될 때 검색돼요.HttpClient인스턴스가 빌드된 후 시스템 전체 값을 변경하는 것(예:ProxySelector.setDefault(ProxySelector)나SSLContext.setDefault(SSLContext)을 호출)은 이미 빌드된 인스턴스에 아무 효과가 없어요 - Returns: 새
HttpClient - Throws: UncheckedIOException - 새
HttpClient를 빌드하는 데 필요한 기반 IO 리소스를 할당할 수 없을 때
newBuilder
public static HttpClient.Builder newBuilder()
새 HttpClient 빌더를 만들어요. 이 메서드가 반환한 빌더들은 기본 HttpClient 구현의 인스턴스를 만들어요.
- Returns:
HttpClient.Builder
cookieHandler
public abstract Optional<CookieHandler> cookieHandler()
이 클라이언트의 CookieHandler를 담은 Optional을 반환해요. 이 클라이언트의 빌더에 CookieHandler가 설정되지 않았으면 Optional은 비어 있어요.
- Returns: 이 클라이언트의
CookieHandler를 담은Optional
connectTimeout
public abstract Optional<Duration> connectTimeout()
이 클라이언트의 연결 타임아웃 기간을 담은 Optional을 반환해요. 클라이언트의 빌더에 연결 타임아웃 기간이 설정되지 않았으면 Optional은 비어 있어요.
- Returns: 이 클라이언트의 연결 타임아웃 기간을 담은
Optional
followRedirects
public abstract HttpClient.Redirect followRedirects()
이 클라이언트의 리다이렉트 따라가기 정책을 반환해요. 리다이렉트 정책을 지정하지 않는 빌더가 만든 클라이언트의 기본 값은 NEVER이에요.
- Returns: 이 클라이언트의 리다이렉트 따라가기 설정
proxy
public abstract Optional<ProxySelector> proxy()
이 클라이언트에 공급된 ProxySelector를 담은 Optional을 반환해요. 이 클라이언트의 빌더에 프록시 선택기가 설정되지 않았으면 Optional은 비어 있어요. 이 메서드가 빈 옵셔널을 반환해도, HttpClient는 HTTP 요청을 보내는 데 사용되는 노출되지 않은 기본 프록시 선택기를 여전히 가질 수 있어요.
- Returns: 이 클라이언트에 공급된 프록시 선택기를 담은
Optional
sslContext
public abstract SSLContext sslContext()
이 클라이언트의 SSLContext를 반환해요. 이 클라이언트의 빌더에 SSLContext가 설정되지 않았으면 기본 컨텍스트가 반환돼요.
- Returns: 이 클라이언트의
SSLContext
sslParameters
public abstract SSLParameters sslParameters()
이 클라이언트의 SSLParameters의 복사본을 반환해요. 클라이언트의 빌더에 SSLParameters가 설정되지 않았으면 클라이언트가 사용할 구현별 기본 매개변수 집합이 반환돼요.
- Returns: 이 클라이언트의
SSLParameters
authenticator
public abstract Optional<Authenticator> authenticator()
이 클라이언트에 설정된 Authenticator를 담은 Optional을 반환해요. 이 클라이언트의 빌더에 Authenticator가 설정되지 않았으면 Optional은 비어 있어요.
- Returns: 이 클라이언트의
Authenticator를 담은Optional
version
public abstract HttpClient.Version version()
이 클라이언트의 선호 HTTP 프로토콜 버전을 반환해요. 기본 값은 HttpClient.Version.HTTP_2예요.
- Implementation Note: 제약 조건도 프로토콜 버전 선택에 영향을 줄 수 있어요. 예를 들어 HTTP/2가 프록시를 통해 요청되고 구현이 이 모드를 지원하지 않으면 HTTP/1.1이 사용될 수 있어요
- Returns: 요청된 HTTP 프로토콜 버전
executor
public abstract Optional<Executor> executor()
이 클라이언트의 Executor를 담은 Optional을 반환해요. 이 클라이언트의 빌더에 Executor가 설정되지 않았으면 Optional은 비어 있어요. 이 메서드가 빈 옵셔널을 반환해도, HttpClient는 비동기·의존 작업을 실행하는 데 사용되는 노출되지 않은 기본 실행자를 여전히 가질 수 있어요.
- Returns: 이 클라이언트의
Executor를 담은Optional
send
public abstract <T> HttpResponse<T> send(HttpRequest request,
HttpResponse.BodyHandler<T> responseBodyHandler)
throws IOException,
InterruptedException
이 클라이언트를 사용해 주어진 요청을 보내며, 필요하면 응답을 얻기 위해 블록해요. 반환된 HttpResponse<T>는 응답 상태, 헤더, 본문을 담고 있어요(주어진 응답 본문 핸들러가 처리한 대로). 연산이 인터럽트되면 기본 HttpClient 구현은 HTTP 교환을 취소하려고 시도하고 InterruptedException이 던져져요. 취소 요청이 정확히 언제 고려되는지에 대한 보장은 없어요. 특히 요청은 서버에 여전히 보내질 수 있는데, 그 처리가 다른 스레드에서 이미 비동기적으로 시작되었을 수 있고 기반 리소스는 비동기적으로만 해제될 수 있기 때문이에요. HTTP/1.1에서는 취소 시도가 기반 연결을 갑자기 닫게 할 수 있어요. HTTP/2에서는 취소 시도가 스트림을 리셋하게 할 수 있으며, 어떤 상황에서는 — 예를 들어 스레드가 기반 소켓에 쓰려고 하는 중일 때 — 연결도 갑자기 닫히게 할 수 있어요.
- Type Parameters: T - 응답 본문 타입
- Parameters: request - 요청
- Returns: 응답
- Throws: IOException - 보내거나 받는 동안 I/O 오류가 발생하거나 클라이언트가 종료되었을 때
sendAsync
public abstract <T>
CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request,
HttpResponse.BodyHandler<T> responseBodyHandler)
이 클라이언트를 사용해 주어진 요청을 주어진 응답 본문 핸들러로 비동기적으로 보내요. sendAsync(request, responseBodyHandler, null)과 동등해요.
- Type Parameters: T - 응답 본문 타입
- Parameters: request - 요청
- Returns:
CompletableFuture<HttpResponse<T>> - Throws: IllegalArgumentException - request 인자가
HttpRequest.Builder가 명시한 대로 유효하게 빌드될 수 있는 요청이 아닐 때
sendAsync
public abstract <T>
CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request,
HttpResponse.BodyHandler<T> responseBodyHandler,
HttpResponse.PushPromiseHandler<T> pushPromiseHandler)
이 클라이언트를 사용해 주어진 요청을 주어진 응답 본문 핸들러와 push promise 핸들러로 비동기적으로 보내요. 반환된 completable future는 성공적으로 완료되면 응답 상태, 헤더, 본문을 담은 HttpResponse<T>로 완료돼요(주어진 응답 본문 핸들러가 처리한 대로). 받은 push promise(있으면)는 주어진 pushPromiseHandler가 처리해요. null 값의 pushPromiseHandler는 어떤 push promise도 거부해요. 반환된 completable future는 다음으로 예외적으로 완료돼요:
IOException- 보내거나 받는 동안 I/O 오류가 발생하거나 클라이언트가 종료되었을 때SecurityException- 보안 관리자가 설치되어 있고 주어진 요청의 URL 또는 (구성된 경우) 프록시에 대한 접근을 거부할 때
기본 HttpClient 구현은 취소 가능한(cancelable) CompletableFuture 객체를 반환해요. 취소 가능한 future에서 파생된 CompletableFuture 객체도 스스로 취소 가능해요. 완료되지 않은 취소 가능한 future에서 cancel(true)를 호출하면 기반 리소스를 가능한 한 빨리 해제하려는 노력으로 HTTP 교환을 취소하려고 시도해요. 취소 요청이 정확히 언제 고려되는지에 대한 보장은 없어요. 특히 요청은 서버에 여전히 보내질 수 있는데, 그 처리가 다른 스레드에서 이미 비동기적으로 시작되었을 수 있고 기반 리소스는 비동기적으로만 해제될 수 있기 때문이에요. HTTP/1.1에서는 취소 시도가 기반 연결을 갑자기 닫게 할 수 있어요. HTTP/2에서는 취소 시도가 스트림을 리셋하게 할 수 있어요.
- Type Parameters: T - 응답 본문 타입
- Parameters: request - 요청
- Returns:
CompletableFuture<HttpResponse<T>> - Throws: IllegalArgumentException - request 인자가
HttpRequest.Builder가 명시한 대로 유효하게 빌드될 수 있는 요청이 아닐 때
newWebSocketBuilder
public WebSocket.Builder newWebSocketBuilder()
새 WebSocket 빌더를 만들어요(선택 연산).
HttpClient client = HttpClient.newHttpClient();
CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()
.buildAsync(URI.create("ws://websocket.example.com"), listener);
- Implementation Requirements: 이 메서드의 기본 구현은
UnsupportedOperationException을 던져요.newHttpClient()나newBuilder()로 얻은 클라이언트들은 WebSocket 빌더를 반환해요 - Implementation Note: 빌더와 그것으로 만들어진 WebSocket 모두 비차단(non-blocking) 방식으로 동작해요. 즉 그 메서드들은
CompletableFuture를 반환하기 전에 블록하지 않아요. 비동기 작업은 이HttpClient의 실행자에서 실행돼요.Listener.onClose가 반환한CompletionStage가 완료되면 WebSocket은 받은 메시지와 같은 코드와 빈 reason을 가진 Close 메시지를 보낼 거예요 - Returns:
WebSocket.Builder - Throws: UnsupportedOperationException - 이
HttpClient가 WebSocket 지원을 제공하지 않을 때
shutdown
public void shutdown()
이전에 send나 sendAsync로 제출된 요청은 완료까지 실행되지만 새 요청은 받아들이지 않는 정돈된 종료를 시작해요. 요청을 완료까지 실행하는 것은 몇 가지 연산을 백그라운드에서 실행하는 것을 수반할 수 있는데, 응답이 전달될 때까지 기다리는 것도 포함하며, 요청이 완료된 것으로 간주될 때까지 모두 완료까지 실행되어야 해요. 이미 종료되었다면 이 메서드 호출은 추가 효과가 없어요. 이 메서드는 이전에 제출된 요청이 실행을 완료할 때까지 기다리지 않아요. 그러려면 awaitTermination이나 close를 사용하세요.
- Implementation Requirements: 이 메서드의 기본 구현은 아무것도 하지 않아요. 하위 클래스는 적절한 동작을 구현하도록 이 메서드를 재정의해야 해요
- Since: 21
- See Also: HttpClient 닫기에 대한 Implementation Note
awaitTermination
public boolean awaitTermination(Duration duration)
throws InterruptedException
종료 요청 후 모든 연산이 실행을 완료할 때까지, 또는 duration이 경과할 때까지, 또는 현재 스레드가 인터럽트될 때까지 블록해요. 그중 먼저 일어나는 것에 따라요. 연산은 이전에 send나 sendAsync로 제출된 요청을 완료까지 실행하는 데 필요한 어떤 작업이든 해요. 이 메서드는 대기할 duration이 0보다 작거나 같으면 기다리지 않아요. 그 경우 메서드는 스레드가 종료되었는지만 검사해요.
- Implementation Requirements: 이 메서드의 기본 구현은 null 인자를 검사하지만, 그 외에는 아무것도 하지 않고 true를 반환해요. 하위 클래스는 적절한 동작을 구현하도록 이 메서드를 재정의해야 해요
- Parameters: duration - 대기할 최대 시간
- Returns: 이 클라이언트가 종료되었으면 true, 종료 전에 타임아웃이 경과했으면 false
- Throws: InterruptedException - 기다리는 동안 인터럽트되었을 때
- Since: 21
- See Also: HttpClient 닫기에 대한 Implementation Note
isTerminated
public boolean isTerminated()
종료 후 모든 연산이 완료되었으면 true를 반환해요. 연산은 이전에 send나 sendAsync로 제출된 요청을 완료까지 실행하는 데 필요한 어떤 작업이든 해요. shutdown이나 shutdownNow가 먼저 호출되지 않으면 isTerminated는 절대 true가 되지 않는다는 점에 주의하세요.
- Implementation Requirements: 이 메서드의 기본 구현은 아무것도 하지 않고 false를 반환해요. 하위 클래스는 적절한 동작을 구현하도록 이 메서드를 재정의해야 해요
- Returns: 종료 후 모든 작업이 완료되었으면 true
- Since: 21
- See Also: HttpClient 닫기에 대한 Implementation Note
shutdownNow
public void shutdownNow()
이 메서드는 즉시 종료를 시작하려고 시도해요. 이 메서드의 구현은 활발히 실행 중인 연산을 인터럽트하려고 시도할 수 있어요. 연산은 이전에 send나 sendAsync로 제출된 요청을 완료까지 실행하는 데 필요한 어떤 작업이든 해요. 인터럽트되었을 때 활발히 실행 중인 연산의 동작은 정의되지 않아요. 특히 인터럽트된 연산이 종료될 것이라는 보장은 없고, 이 연산들을 기다리는 코드가 언제라도 통보될 것이라는 보장도 없어요.
- Implementation Requirements: 이 메서드의 기본 구현은 단순히
shutdown()을 호출해요. 하위 클래스는 적절한 동작을 구현하도록 이 메서드를 재정의해야 해요 - Since: 21
- See Also: HttpClient 닫기에 대한 Implementation Note
close
public void close()
이전에 send나 sendAsync로 제출된 요청은 완료까지 실행되지만 새 요청은 받아들이지 않는 정돈된 종료를 시작해요. 요청을 완료까지 실행하는 것은 몇 가지 연산을 백그라운드에서 실행하는 것을 수반할 수 있는데, 응답이 전달될 때까지 기다리는 것도 포함해요. 이 메서드는 모든 연산이 실행을 완료하고 클라이언트가 종료될 때까지 기다려요. 기다리는 동안 인터럽트되면 이 메서드는 shutdownNow()를 호출해 모든 연산을 중지하려고 시도할 수 있어요. 그런 다음 활발히 실행 중인 연산이 모두 완료될 때까지 계속 기다려요. 이 메서드가 반환하기 전에 인터럽트 상태가 다시 설정될 거예요. 이미 종료되었다면 이 메서드 호출은 효과가 없어요.
- Specified by:
AutoCloseable인터페이스의close - Implementation Requirements: 기본 구현은
shutdown()을 호출하고awaitTermination으로 작업이 실행을 완료할 때까지 기다려요 - Since: 21
- See Also: HttpClient 닫기에 대한 Implementation Note