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.