java - ¿Cuál es la diferencia entre CloseableHttpClient y HttpClient en Apache HttpClient API?
apache-httpclient-4.x (6)
En la próxima versión principal de la biblioteca, la interfaz de HttpClient
se extenderá a Closeable
. Hasta entonces, se recomienda utilizar CloseableHttpClient
si no se requiere compatibilidad con versiones anteriores de 4.x (4.0, 4.1 y 4.2).
Estoy estudiando una aplicación desarrollada por nuestra empresa. Utiliza la biblioteca Apache HttpClient. En el código fuente utiliza la clase HttpClient
para crear instancias para conectarse a un servidor.
Quiero aprender sobre Apache HttpClient y he ido a través de este conjunto de ejemplos . Todos los ejemplos usan CloseableHttpClient
lugar de HttpClient
. Así que creo que CloseableHttpClient
es una versión extendida de HttpClient
. Si este es el caso, tengo dos preguntas:
- ¿Cuál es la diferencia entre estos dos?
- ¿Qué clase se recomienda usar para mi nuevo desarrollo?
Las otras respuestas no parecen abordar por qué close()
es realmente necesario. * 2
Duda de la respuesta "HttpClient resource desasignación".
Se menciona en el antiguo 3.x httpcomponents Reference , que data de hace mucho tiempo y tiene mucha diferencia con 4.x HC. Además, la explicación es tan breve que no dice qué es este recurso subyacente.
Hice algunas investigaciones sobre el código fuente de la versión 4.5.2, descubrí que las implementaciones de CloseableHttpClient:close()
básicamente solo cierran su administrador de conexión.
(Para su información) Es por eso que cuando utiliza un PoolingClientConnectionManager
compartido y llama al cliente close()
, se producirá la excepción java.lang.IllegalStateException: Connection pool shut down
. Para evitarlo, setConnectionManagerShared
funciona.
Prefiero no hacer CloseableHttpClient:close()
después de cada solicitud
Solía crear una nueva instancia de cliente http cuando hacía la solicitud y finalmente la cerraba. En este caso, sería mejor no llamar a close()
. Dado que, si el administrador de conexión no tiene indicador "compartido", se cerrará, lo que es demasiado caro para una única solicitud.
De hecho, también encontré en la biblioteca clj-http , una envoltura de Clojure sobre Apache HC 4.5, no se llama close()
en absoluto. Ver func request
en el archivo core.clj
Tenía la misma pregunta. Las otras respuestas no parecen abordar por qué close () es realmente necesario. Además, Op parecía estar luchando por encontrar la forma preferida de trabajar con HttpClient, et al.
De acuerdo con 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.
Además, las relaciones son las siguientes:
HttpClient
(interfaz)Implementado por:
CloseableHttpClient - ThreadSafe.
DefaultHttpClient
- ThreadSafe PERO deprecated , utiliceHttpClientBuilder
lugar.
HttpClientBuilder
- NO ThreadSafe, PERO crea ThreadSafe CloseableHttpClient.
- Úselo para crear CUSTOM
CloseableHttpClient
.
HttpClients
- NO ThreadSafe, PERO crea ThreadSafe CloseableHttpClient.
- Úselo para crear DEFAULT o MINIMAL
CloseableHttpClient
.
La forma preferida según Apache:
CloseableHttpClient httpclient = HttpClients.createDefault();
El ejemplo que dan hace httpclient.close()
en la cláusula finally
, y también hace uso de ResponseHandler
también.
Como alternativa, la forma en que lo hace mkyong también es un poco interesante:
HttpClient client = HttpClientBuilder.create().build();
No muestra una client.close()
a client.close()
pero creo que es necesario, ya que el client
sigue siendo una instancia de CloseableHttpClient
.
CloseableHttpClient
es la clase base de la biblioteca httpclient, la que todas las implementaciones usan. Otras subclases son en su mayor parte obsoletas.
HttpClient
es una interfaz para esta clase y otras clases.
A continuación, debe utilizar el CloseableHttpClient
en su código y crearlo utilizando HttpClientBuilder
. Si necesita envolver al cliente para agregar un comportamiento específico, debe usar interceptores de solicitud y respuesta en lugar de envolver con HttpClient
.
Esta respuesta se dio en el contexto de httpclient-4.3.
HttpClient
no es una clase, es una interfaz. No puedes usarlo para el desarrollo en la forma en que te refieres.
Lo que quiere es una clase que implemente la interfaz HttpClient
, y que sea CloseableHttpClient
.
- El punto de entrada principal de la API HttpClient es la interfaz HttpClient.
- La función más esencial de HttpClient es ejecutar métodos HTTP.
- La ejecución de un método HTTP implica uno o varios intercambios de solicitud HTTP / respuesta HTTP, generalmente manejados internamente por HttpClient.
- CloseableHttpClient es una clase abstracta que es la implementación base de HttpClient que también implementa java.io.Closeable.
Aquí hay un ejemplo de proceso de ejecución de solicitud en su forma más simple:
CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://localhost/"); CloseableHttpResponse response = httpclient.execute(httpget); try { //do something } finally { response.close(); }
Desasignación de recurso HttpClient: cuando una instancia CloseableHttpClient ya no se necesita y está a punto de salir del alcance, el administrador de conexión asociado debe cerrarse llamando al método CloseableHttpClient # close ().
CloseableHttpClient httpclient = HttpClients.createDefault(); try { //do something } finally { httpclient.close(); }
ver la Reference para aprender los fundamentos.
@Scadge Desde Java 7, el uso de la declaración try-with-resources asegura que cada recurso se cierre al final de la instrucción.
try(CloseableHttpClient httpclient = HttpClients.createDefault()){
//do something with httpclient here
}