J'étudie une application développée par notre société. Il utilise la bibliothèque Apache HttpClient. Dans le code source, il utilise la classe HttpClient
pour créer des instances permettant de se connecter à un serveur.
Je veux en savoir plus sur Apache HttpClient et j'ai passé au travers cette série d'exemples . Tous les exemples utilisent CloseableHttpClient
au lieu de HttpClient
. Donc, je pense que CloseableHttpClient
est une version étendue de HttpClient
. Si tel est le cas, j'ai deux questions:
Voici un exemple de processus d'exécution de requête dans sa forme la plus simple:
CloseableHttpClient httpclient = HttpClients.createDefault (); HttpGet httpget = new HttpGet ("http: // localhost /"); CloseableHttpResponse response = httpclient.execute (httpget); try { // faire quelque chose } enfin { response.close (); }
Désallocation de ressource HttpClient: Lorsqu'une instance CloseableHttpClient n'est plus nécessaire et est sur le point de sortir de son périmètre, le gestionnaire de connexions qui lui est associé doit être fermé par un appel. la méthode CloseableHttpClient # close ().
CloseableHttpClient httpclient = HttpClients.createDefault (); Try { // faire quelque chose } Finalement { Httpclient.close (); }
voir le Référence pour apprendre les bases.
@Scadge Since Java 7, utilisation de l'instruction try-with-resources ) garantit que chaque ressource est fermée à la fin de l'instruction.
try(CloseableHttpClient httpclient = HttpClients.createDefault()){
//do something with httpclient here
}
Avait la même question. Les autres réponses ne semblent pas expliquer pourquoi close () est vraiment nécessaire? De plus, Op semblait avoir du mal à trouver la meilleure façon de travailler avec HttpClient, et al.
Selon 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.
De plus, les relations vont comme suit:
HttpClient
(interface)implementé par:
CloseableHttpClient
- ThreadSafe.
DefaultHttpClient
- ThreadSafe BUT obsolète , utilisezHttpClientBuilder
à la place.
HttpClientBuilder
- PAS ThreadSafe, mais crée ThreadSafeCloseableHttpClient
.
- Utilisez pour créer CUSTOM
CloseableHttpClient
.
HttpClients
- PAS ThreadSafe, mais crée ThreadSafeCloseableHttpClient
.
- Utilisez pour créer DEFAULT ou MINIMAL
CloseableHttpClient
.
La manière préférée selon Apache:
CloseableHttpClient httpclient = HttpClients.createDefault();
L'exemple ils donnent ce que fait httpclient.close()
dans la clause finally
, et utilise également ResponseHandler
.
En guise d'alternative, la manière dont mkyong le fait est également un peu intéressante:
HttpClient client = HttpClientBuilder.create().build();
Il ne montre pas un appel client.close()
mais je pense que c'est nécessaire, puisque client
est toujours une instance de CloseableHttpClient
.
Les autres réponses ne semblent pas expliquer pourquoi close()
est vraiment nécessaire? * 2
Il est mentionné dans la version 3.x httpcomponents doc , qui est longue et très différente de la version 4.x HC. En outre, l'explication est si brève que la ressource sous-jacente n'est pas précisée.
J'ai fait des recherches sur le code source de la version 4.5.2, j'ai découvert que les implémentations de CloseableHttpClient:close()
ne ferment que son gestionnaire de connexions.
(FYI) C'est pourquoi, lorsque vous utilisez un PoolingClientConnectionManager
partagé et appelez le client close()
, une exception Java.lang.IllegalStateException: Connection pool shut down
Se produira. Pour éviter, setConnectionManagerShared
fonctionne.
CloseableHttpClient:close()
après chaque requêteJ'avais l'habitude de créer une nouvelle instance de client http lors de la requête et de la fermer. Dans ce cas, il vaut mieux ne pas appeler close()
. Dans la mesure où, si le gestionnaire de connexions n'a pas d'indicateur "partagé", ce sera l'arrêt, ce qui est trop coûteux pour une seule demande.
En fait, j'ai aussi trouvé dans la bibliothèque clj-http , un wrapper Clojure sur Apache HC 4.5, n'appelle pas du tout close()
. Voir func request
dans le fichier core.clj
Dans la prochaine version majeure de la bibliothèque, l'interface HttpClient
s'étendra Closeable
. Jusque-là, il est recommandé d'utiliser CloseableHttpClient
si la compatibilité avec les versions 4.x antérieures (4.0, 4.1 et 4.2) n'est pas requise.
HttpClient
n'est pas une classe, c'est une interface. Vous ne pouvez pas l'utiliser pour le développement de la façon dont vous voulez dire.
Ce que vous voulez, c'est une classe qui implémente l'interface HttpClient
, c'est-à-dire CloseableHttpClient
.
CloseableHttpClient
est la classe de base de la bibliothèque httpclient, celle utilisée par toutes les implémentations. Les autres sous-classes sont pour la plupart obsolètes.
Le HttpClient
est une interface pour cette classe et d'autres classes.
Vous devez ensuite utiliser CloseableHttpClient
dans votre code et le créer à l'aide de HttpClientBuilder
. Si vous avez besoin d'encapsuler le client pour ajouter un comportement spécifique, vous devez utiliser des intercepteurs de requête et de réponse au lieu d'encapsuler avec le HttpClient
.
Cette réponse a été donnée dans le contexte de httpclient-4.3.