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

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

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

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



답변

  • 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
}


답변

같은 질문을했습니다. 다른 답변은 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.


답변

다른 답변은 왜 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 를 참조하십시오.


답변

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


답변

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

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


답변

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

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

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

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


답변

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

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

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

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

Jules에 대한 답변

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

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

노트 :

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