Apache HttpClient API에서 CloseableHttpClient와 HttpClient의 차이점은 무엇입니까?


84

우리 회사에서 개발 한 애플리케이션을 연구 중입니다. Apache HttpClient 라이브러리를 사용합니다. 소스 코드에서는 HttpClient클래스를 사용하여 서버에 연결할 인스턴스를 만듭니다.

Apache HttpClient에 대해 배우고 싶고이 예제 세트를 살펴 보았습니다 . 모든 예제는 CloseableHttpClient대신 HttpClient. 내가 생각하는 그래서 것은 CloseableHttpClient의 확장 버전입니다 HttpClient. 이 경우 두 가지 질문이 있습니다.

  • 이 둘의 차이점은 무엇입니까?
  • 새로운 개발에 어떤 클래스를 사용하는 것이 좋습니까?

7
문서는 나에게 매우 분명해 보인다. "Closeable을 구현하는 HttpClient의 기본 구현"-HttpClient는 인터페이스입니다. CloseableHttpClient는 추상 클래스이지만 AutoCloseable을 구현하기 때문에 try-with-resources 문에서 사용할 수 있습니다.
Jon Skeet 2014

3
@JonSkeet 그 정도는 분명하지만 HttpClient인스턴스 를 닫는 것이 얼마나 중요 합니까? 중요한 경우 close()메서드가 기본 인터페이스의 일부가 아닌 이유는 무엇입니까?
Jules

3
@Jules : 나는 대답 할 HttpClient에 대해 충분히 알지 못합니다. (
Jon Skeet

연결을 기초하는 것은 자동으로 연결 관리자로 다시 출시되기 때문에 가까운 필요가 기본 인터페이스의 일부가 될 수 없습니다
Jeril Kuruvila을

답변:


100
  • HttpClient API의 주요 진입 점은 HttpClient 인터페이스입니다.
  • HttpClient의 가장 중요한 기능은 HTTP 메서드를 실행하는 것입니다.
  • HTTP 메서드 실행에는 일반적으로 HttpClient에 의해 내부적으로 처리되는 하나 또는 여러 HTTP 요청 / HTTP 응답 교환이 포함됩니다.

  • CloseableHttpClient는 java.io.Closeable을 구현하는 HttpClient의 기본 구현 인 추상 클래스입니다.
  • 다음은 가장 간단한 형태의 요청 실행 프로세스의 예입니다.

    CloseableHttpClient httpclient = HttpClients.createDefault ();
    HttpGet httpget = new HttpGet ( "http : // localhost /");
    CloseableHttpResponse 응답 = httpclient.execute (httpget);
    {
        // 무언가
    } 드디어 {
        response.close ();
    }

  • HttpClient 리소스 할당 취소 : CloseableHttpClient 인스턴스가 더 이상 필요하지 않고 범위를 벗어나려는 경우 CloseableHttpClient # close () 메서드를 호출하여 연결된 연결 관리자를 종료해야합니다.

    CloseableHttpClient httpclient = HttpClients.createDefault ();
    {
        // 무언가
    } 드디어 {
        httpclient.close ();
    }

기본 사항 을 배우 려면 참조참조 하십시오 .


@Scadge Java 7부터 try-with-resources 문을 사용하면 각 리소스가 문 끝에서 닫힙니다. 클라이언트와 각 응답 모두에 사용할 수 있습니다.

try(CloseableHttpClient httpclient = HttpClients.createDefault()){

    // e.g. do this many times
    try (CloseableHttpResponse response = httpclient.execute(httpget)) {
    //do something
    }

    //do something else with httpclient here
}

58
이 대답은 질문을 던집니다. HttpClient에서 close ()를 호출하면 그렇지 않으면 일어나지 않을 일이 발생합니까? 적절한 시간 / 장소에서 close ()를 호출하지 않으면 연결이 누출됩니까? close () 호출이 실제로 필요하지 않았을 때 다시 연결하도록하여 성능에 조기에 영향을 미칩니 까?
gilbertpilz

4
이 질문에 대한 답을 찾기 위해 httpclient의 코드를 살펴 보았습니다. 대답은 close 메서드가 내부 상태를 닫는 데 사용된다는 것입니다. HTTPClient의 일부 구현 (httpclient lib에 있음)은 풀링 된 연결에 PooledHttpClientConnectionManager와 같은 영구 리소스를 사용하도록 구성 할 수 있으며 이러한 방법이 없으면 필요한 경우 이러한 리소스를 정리할 수 없습니다.
Deadron

@SugarPudi는 위의 예에서 우리가 종료해야 하는가 httpget
Kasun Siyambalapitiya

여기서 추상 클래스 (CloseableHttpClient)의 메서드를 어떻게 호출 할 수 있습니까? 구체적인 하위 클래스를 먼저 만들어야하지 않습니까?
illcar

@illcar 개념 이해하기 위해이 답변을 throuth 이동하십시오 stackoverflow.com/a/4321402/2830834
사가르 Pudi

27

같은 질문을했습니다. 다른 답변은 close ()가 정말로 필요한 이유를 다루지 않는 것 같습니다. 또한 Op는 HttpClient 등으로 작업하는 데 선호되는 방법을 파악하는 데 어려움을 겪고있는 것 같습니다.


Apache 에 따르면 :

// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
// the user MUST call CloseableHttpResponse#close() from a finally clause.

또한 관계는 다음과 같이 진행됩니다.

HttpClient (상호 작용)

구현 :

CloseableHttpClient -ThreadSafe.

DefaultHttpClient- 스레드하지만 사용되지는 사용 HttpClientBuilder대신.

HttpClientBuilder-ThreadSafe는 아니지만 ThreadSafe를 만듭니다 CloseableHttpClient.

  • CUSTOM을 만드는 데 사용합니다 CloseableHttpClient.

HttpClients-ThreadSafe는 아니지만 ThreadSafe를 만듭니다 CloseableHttpClient.

  • DEFAULT 또는 MINIMAL을 만드는 데 사용합니다 CloseableHttpClient.

Apache에 따른 선호하는 방법 :

CloseableHttpClient httpclient = HttpClients.createDefault();

그들이 제공 하는 예httpclient.close()finally절에서 수행되며 또한 사용 ResponseHandler합니다.


대안으로 mkyong이하는 방식도 약간 흥미 롭습니다.

HttpClient client = HttpClientBuilder.create().build();

그는 client.close()전화를 표시하지 않지만 client여전히의 인스턴스 이기 때문에 필요하다고 생각합니다 CloseableHttpClient.


15

다른 답변은 왜 close()정말 필요한지 설명하지 않는 것 같습니다 . * 2

"HttpClient 리소스 할당 해제"에 대한 대답에 의문을 제기하십시오.

오래 전 3.x httpcomponents doc 에서 언급되었으며 4.x HC와 많은 차이가 있습니다. 게다가 설명이 너무 짧아서이 기본 리소스가 무엇인지 말하지 않습니다.

4.5.2 릴리스 소스 코드에 대한 조사를 수행 한 결과의 구현은 CloseableHttpClient:close()기본적으로 연결 관리자 만 닫습니다.

(참고로) 그래서 shared를 사용하고 PoolingClientConnectionManagerclient를 호출 close()하면 예외 java.lang.IllegalStateException: Connection pool shut down가 발생합니다. 피하려면 setConnectionManagerShared작동합니다.

나는 매 요청 후에 는 하지 않는 것을 선호한다CloseableHttpClient:close()

요청을 할 때 새 http 클라이언트 인스턴스를 만들고 마지막으로 닫았습니다. 이 경우을 호출하지 않는 것이 좋습니다 close(). 연결 관리자에 "공유"플래그가 없으면 종료되므로 단일 요청에 너무 비쌉니다.

사실, Apache HC 4.5 이상의 Clojure 래퍼 인 clj-http 라이브러리 에서도 전혀 호출하지 않습니다 close(). core.cljrequest 파일의 func 를 참조하십시오.


1
setConnectionManagerShared를 사용하고 모든 요청 후에 close ()를 호출하는 것보다 더 나은 이유를 설명해 주시겠습니까?
zyfo2

9

다음 주요 버전의 라이브러리 HttpClient인터페이스에서는 Closeable. 그때까지는 CloseableHttpClient이전 4.x 버전 (4.0, 4.1 및 4.2)과의 호환성이 필요하지 않은 경우 사용 하는 것이 좋습니다 .


8

HttpClient클래스가 아니라 인터페이스입니다. 당신이 의미하는 방식으로 개발에 사용할 수 없습니다.

당신이 원하는 것은 HttpClient인터페이스 를 구현하는 클래스입니다 CloseableHttpClient.


2

CloseableHttpClient모든 구현에서 사용하는 httpclient 라이브러리의 기본 클래스입니다. 다른 하위 클래스는 대부분 사용되지 않습니다.

HttpClient이 클래스와 다른 클래스에 대한 인터페이스입니다.

그런 다음 CloseableHttpClient코드에서를 사용하고 HttpClientBuilder. 특정 동작을 추가하기 위해 클라이언트를 래핑해야하는 경우 HttpClient.

이 답변은 httpclient-4.3의 컨텍스트에서 제공되었습니다.


0

Jon Skeet은 다음과 같이 말했습니다.

문서는 나에게 매우 명확 해 보인다. "Closeable을 구현하는 HttpClient의 기본 구현"-HttpClient는 인터페이스입니다. CloseableHttpClient는 추상 클래스이지만 AutoCloseable을 구현하기 때문에 try-with-resources 문에서 사용할 수 있습니다.

그러나 Jules는 다음과 같이 물었습니다.

@JonSkeet 그 정도는 분명하지만 HttpClient 인스턴스를 닫는 것이 얼마나 중요합니까? 중요한 경우 close () 메서드가 기본 인터페이스의 일부가 아닌 이유는 무엇입니까?

Jules에 대한 답변

모든 실행 후 기본 연결이 자동으로 연결 관리자로 다시 해제되므로 닫기는 기본 인터페이스의 일부일 필요가 없습니다.

try-with-resources 문을 수용하기 위해. Closeable을 구현하는 것은 필수입니다. 따라서 CloseableHttpClient에 포함되었습니다 .

노트 :

CloseableHttpClient를 확장하는 AbstractHttpClient의 close 메서드는 더 이상 사용되지 않으므로 해당 소스 코드를 찾을 수 없습니다.


이것은 여전히 ​​"HttpClient 인스턴스를 닫는 것이 얼마나 중요합니까?"라고 대답하지 않는 것 같습니다.
Vivek Chavda
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.