Ich studiere eine von unserer Firma entwickelte Anwendung. Es verwendet die Apache HttpClient-Bibliothek. Im Quellcode werden mithilfe der HttpClient
Klasse Instanzen erstellt, um eine Verbindung zu einem Server herzustellen.
Ich möchte mehr über Apache HttpClient erfahren und habe diese Beispiele durchgearbeitet . Alle Beispiele verwenden CloseableHttpClient
anstelle von HttpClient
. Also ich denke CloseableHttpClient
ist eine erweiterte Version von HttpClient
. Wenn dies der Fall ist, habe ich zwei Fragen:
- Was ist der Unterschied zwischen diesen beiden?
- Welche Klasse wird für meine Neuentwicklung empfohlen?
java
apache
http
apache-httpclient-4.x
Nayana Adassuriya
quelle
quelle
HttpClient
Instanzen zu schließen ? Wenn es wichtig ist, warum ist dieclose()
Methode nicht Teil der Basisschnittstelle?Antworten:
Hier ist ein Beispiel für den Anforderungsausführungsprozess in seiner einfachsten Form:
Freigabe der HttpClient-Ressource: Wenn eine Instanz CloseableHttpClient nicht mehr benötigt wird und bald den Gültigkeitsbereich verlässt, muss der damit verbundene Verbindungsmanager durch Aufrufen der CloseableHttpClient # close () -Methode heruntergefahren werden.
Weitere Informationen finden Sie in der Referenz .
@Scadge Seit Java 7 stellt die Verwendung der Anweisung try-with-resources sicher, dass jede Ressource am Ende der Anweisung geschlossen wird. Es kann sowohl für den Client als auch für jede Antwort verwendet werden
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 }
quelle
httpget
auchHatte die gleiche Frage. Die anderen Antworten scheinen nicht zu sagen, warum close () wirklich notwendig ist. Außerdem schien Op Schwierigkeiten zu haben, die bevorzugte Art der Arbeit mit HttpClient et al.
Laut 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.
Darüber hinaus lauten die Beziehungen wie folgt:
Der bevorzugte Weg nach Apache:
Das Beispiel, das sie geben, ist
httpclient.close()
in derfinally
Klausel enthalten und wird auch verwendetResponseHandler
.Als Alternative ist die Art und Weise, wie Mkyong es macht, auch ein bisschen interessant:
Er zeigt keinen
client.close()
Anruf, aber ich würde denken, dass es notwendig ist, daclient
es immer noch eine Instanz von istCloseableHttpClient
.quelle
Die anderen Antworten scheinen nicht zu sagen, warum
close()
das wirklich notwendig ist. * 2Zweifel an der Antwort "HttpClient-Ressourcenfreigabe".
Es wird im alten 3.x httpcomponents- Dokument erwähnt , das lange zurückliegt und einen großen Unterschied zu 4.x HC aufweist. Außerdem ist die Erklärung so kurz, dass sie nicht sagt, was diese zugrunde liegende Ressource ist.
Ich habe einige Nachforschungen über den Quellcode von 4.5.2 angestellt und festgestellt, dass die Implementierung von im
CloseableHttpClient:close()
Grunde nur den Verbindungsmanager schließt.(Zu Ihrer Information) Wenn Sie einen gemeinsam genutzten
PoolingClientConnectionManager
Client und einen Anrufclient verwendenclose()
, tritt daher eine Ausnahmejava.lang.IllegalStateException: Connection pool shut down
auf. Um zu vermeiden,setConnectionManagerShared
funktioniert.Ich mache es lieber nicht
CloseableHttpClient:close()
nach jeder einzelnen AnfrageIch habe bei der Anforderung eine neue http-Client-Instanz erstellt und diese schließlich geschlossen. In diesem Fall ist es besser, nicht anzurufen
close()
. Wenn der Verbindungsmanager kein "freigegebenes" Flag hat, wird er heruntergefahren, was für eine einzelne Anforderung zu teuer ist.Tatsächlich habe ich auch in der Bibliothek gefunden, dass clj-http , ein Clojure-Wrapper über Apache HC 4.5, überhaupt nicht aufruft
close()
. Siehe funcrequest
in der Datei core.cljquelle
In der nächsten Hauptversion wird die Bibliotheksschnittstelle
HttpClient
erweitertCloseable
. Bis dahin wird die Verwendung empfohlen,CloseableHttpClient
wenn keine Kompatibilität mit früheren 4.x-Versionen (4.0, 4.1 und 4.2) erforderlich ist.quelle
HttpClient
ist keine Klasse, es ist eine Schnittstelle. Sie können es nicht so für die Entwicklung verwenden, wie Sie es meinen.Was Sie wollen, ist eine Klasse, die die
HttpClient
Schnittstelle implementiert , und das istCloseableHttpClient
.quelle
CloseableHttpClient
ist die Basisklasse der httpclient-Bibliothek, die von allen Implementierungen verwendet wird. Andere Unterklassen sind größtenteils veraltet.Das
HttpClient
ist eine Schnittstelle für diese Klasse und andere Klassen.Sie sollten dann das
CloseableHttpClient
in Ihrem Code verwenden und es mit dem erstellenHttpClientBuilder
. Wenn Sie den Client umbrechen müssen, um ein bestimmtes Verhalten hinzuzufügen, sollten Sie Anforderungs- und Antwortabfangjäger verwenden, anstatt mit dem umzubrechenHttpClient
.Diese Antwort wurde im Kontext von httpclient-4.3 gegeben.
quelle
Jon Skeet sagte:
Die Dokumentation scheint mir ziemlich klar zu sein: "Basisimplementierung von HttpClient, die auch Closeable implementiert" - HttpClient ist eine Schnittstelle; CloseableHttpClient ist eine abstrakte Klasse. Da sie jedoch AutoCloseable implementiert, können Sie sie in einer Try-with-Resources-Anweisung verwenden.
Aber dann fragte Jules:
@ JonSkeet Das ist klar, aber wie wichtig ist es, HttpClient-Instanzen zu schließen? Wenn es wichtig ist, warum ist die Methode close () nicht Teil der Basisschnittstelle?
Antwort für Jules
Um die Try-with-Resources-Anweisung zu berücksichtigen. Es ist obligatorisch, Closeable zu implementieren. Daher in CloseableHttpClient enthalten .
Hinweis:
Die Methode close in AbstractHttpClient, die CloseableHttpClient erweitert, ist veraltet. Ich konnte den Quellcode dafür nicht finden.
quelle