web-dev-qa-db-fra.com

Quelle est la différence entre CloseableHttpClient et HttpClient dans l'API Apache HttpClient?

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:

  • Quelle est la différence entre ces deux?
  • Quelle classe est recommandée pour mon nouveau développement?
61
Nayana Adassuriya
  • Le point d'entrée principal de l'API HttpClient est l'interface HttpClient.
  • La fonction la plus essentielle de HttpClient est d'exécuter des méthodes HTTP.
  • L'exécution d'une méthode HTTP implique un ou plusieurs échanges requête HTTP/réponse HTTP, généralement gérés en interne par HttpClient.

  • CloseableHttpClient est une classe abstraite qui est l'implémentation de base de HttpClient qui implémente également Java.io.Closeable.
  • 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
}
82
Sagar Pudi

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 , utilisez HttpClientBuilder à la place.

HttpClientBuilder - PAS ThreadSafe, mais crée ThreadSafe CloseableHttpClient.

  • Utilisez pour créer CUSTOM CloseableHttpClient.

HttpClients - PAS ThreadSafe, mais crée ThreadSafe CloseableHttpClient.

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

16
euphoria99

Les autres réponses ne semblent pas expliquer pourquoi close() est vraiment nécessaire? * 2

Doute sur la réponse "désallocation de ressources HttpClient".

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.

Je préfère pas faire CloseableHttpClient:close() après chaque requête

J'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

13
mzhang

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.

8
ok2c

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.

8
M. Sfakianos

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.

2
polve