Jakarta Commons HttpClient
Introducción
Cuando necesitamos realizar tareas de comunicaciones bajo J2SE, normalmente hacemos uso del paquete java.net y sus extensiones.
java.net.HttpURLConnection y java.net.URL son, prácticamente las únicas clases que nos proporciona J2SE para abstraernos un poco de las comunicaciones bajo HTTP. Aunque cualquier tarea se puede hacer usando simplemente las clases que vienen de serie con la plataforma, estas son poco elegantes (en términos de Orientación a Objetos) para conseguir funcionalidad cliente HTTP.
HTTPClient, nos proporciona un amplio y elegante Framework para realizar las tareas de comunicación HTTP en el lado cliente.
Para descargar este excelente subproyecto de Jakarta u obtener una información más extensa, puede dirigirse a
http://jakarta.apache.org/commons/httpclient
Características Principales
Desde mi punto de vista las principales características son:
- Administración automática de Cookies.
- Seguimiento automático de redirecciones.
- Cancelación de peticiones en curso.
- Soporte de gzip para ahorrar ancho de banda en nuestra comunicaciones.
- Administrador de conexiones multihilo para poder tener varias tareas simultaneas en curso. (Descargarnos dos aplicaciones al mismo tiempo, por ejemplo)
- Manejo automático de SSL
- Logs de la información que se envia o recibe: Cabeceras enviadas/recibidas, Cookies, etc. (Muy útil para determinadas aplicaciones o para depuraciones).
- Pool de conexiones para poder reutilizar conexiones sin tener que abrirlas o cerrarlas constantemente.
Lo hace el API, según los parámetros de configuración que se le especifiquen. Por ejemplo, que se cierren automáticamente las conexiones que lleven 2 minutos sin ser usadas. - Poder subir ficheros vía POST sin tener que cargar en memoria en memoria la información que se desea subir.
Vamos a ver un ejemplo
En el siguiente ejemplo se tratan varios de los aspectos más comunes en cualquier comunicación HTTP. En concreto trateremos:
- Haremos una petición GET y otra POST añadiendo cabeceras personalizadas y parámetros.
- Configuraremos el cliente para salir a través de un Proxy
- Nos autentificaremos en caso de que el servidor lo requiera (Autentificación Digest o Basic).
- Seguiremos la redirecciones en caso de que se produzcan.
- Nos conectaremos a un servidor seguro (SSL)
He de resaltar que este API tiene dependencias con otros APIs de Jakarta Commons, por lo que debemos distribuirlos junto a nuestra aplicación para que funcione.
En concreto, estas dependencias son:
- Jakarta Commons Codec. (Este para la gran mayoría de los casos no es necesario)
- Jakarta Commons Logging.
HttpClientTutorial.java
(El ejemplo es autocomentado)
package autentia.tutoriales.httpClient; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.params.HttpMethodParams; import java.io.*; /** * Ejemplo del uso de Jakarta Commons HttpClient * @author Carlos García. Autentia Real Business Solutions * @see http://www.mobiletest.es */ public class HttpClientTutorial { /** * En caso de salir a Internet a tavés de un Proxy, se deberán modificar los siguientes parámetros */ public static final boolean byProxy = false; public static final String ProxyAddress = "TuProxyAddress"; public static final int ProxyPort = 1234; /** * Direcciones que usamos para enviar peticiones */ public static final String TargetURLSSL = "https://www.verisign.com"; public static final String TargetURL = "http://www.autentia.es"; /** * Por defecto haremos una petición HTTP GET. Cambiar a false para peticiones HTTP POST */ public static final boolean ByGet = true; /** * Si queremos hacer conectarnos a un servidor seguro via SSL poner a true la siguiente variable */ public static final boolean BySSL = false; /** * En caso de necesitar autentificacion con el servidor modificar los siguientes parámetros */ public static final boolean Authenticate = false; public static final String UsernameCredentials = "TuUsuario"; public static final String PasswordCredentials = "TuPassword"; /** * Punto de inicio de ejecución del ejemplo. */ public static void main(String[] args) { HttpClient httpClient = null; // Objeto a través del cual realizamos las peticiones HttpMethodBase request = null; // Objeto para realizar las peticiines HTTP GET o POST int status = 0; // Código de la respuesta HTTP BufferedReader reader = null; // Se usa para leer la respuesta a la petición String line = null; // Se usa para leer cada una de las lineas de texto de la respuesta // Instanciamos el objeto httpClient = new HttpClient(); // Especificamos que salimos a través de un Proxy. if (byProxy){ httpClient.getHostConfiguration().setProxy(HttpClientTutorial.ProxyAddress, HttpClientTutorial.ProxyPort); } if (ByGet){ // Invocamos por GET // ¿ Nos conectamos a un servidor seguro ? // Observe que si están bien instalado JSSE (Java Secure Socket Extension), //el código es exactamente igual if (BySSL) { request = new GetMethod(HttpClientTutorial.TargetURLSSL); } else { request = new GetMethod(HttpClientTutorial.TargetURL); } // Le indicamos que realize automáticamente el seguimiento de las redirecciones // en caso de que existan. request.setFollowRedirects(true); // Añadimos los parámetros que deseemos a la petición // GET: http://dominio/pagina?nombre=Carlos+Garc%C3%ADa NameValuePair params[] = {new NameValuePair("nombre", "Carlos García")}; request.setQueryString(params); } else { // Invocamos por POST request = new PostMethod(HttpClientTutorial.TargetURL); // Añadimos los parámetros que deseemos a la petición ((PostMethod) request).addParameter("nombre", "Carlos García"); } try { // Si su servidor requiere autentificación necesitará una línea como la siguiente if (Authenticate){ UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(UsernameCredentials, PasswordCredentials); httpClient.getState().setCredentials( new AuthScope(request.getURI().getHost(), 80, AuthScope.ANY_REALM), credentials); // Indicamos que se autentifique si fuese requerido request.setDoAuthentication(true); } // Indicamos reintente 3 veces en caso de que haya errores. request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, true)); // Añadimos las cabeceras personalizadas que se requieran, de la siguiente forma: request.addRequestHeader("HeadKey", "HeadValue"); // Enviamos una cookie personalizada a las que el CookieManager ya tenga httpClient.getState().addCookie( new Cookie(request.getURI().getHost(), "nombreCookie", "valorCookie", "/", 3600, false)); // Leemos el código de la respuesta HTTP que nos devuelve el servidor status = httpClient.executeMethod(request); // Vemos si la petición se ha realizado satisfactoriamente if (status != HttpStatus.SC_OK) { System.err.println("Error\t" + request.getStatusCode() + "\t" + request.getStatusText() + "\t" + request.getStatusLine()); } else { // Leemos el contenido de la respuesta y realizamos el tratamiento de la misma. // En nuestro caso, simplemente mostramos el resultado por la salida estándar reader = new BufferedReader( new InputStreamReader(request.getResponseBodyAsStream(), request.getResponseCharSet())); line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } } } catch (Exception ex){ System.err.println("Error\t: " + ex.getMessage()); ex.printStackTrace(); } finally { // Liberamos la conexión. (También libera los stream asociados) request.releaseConnection(); } } }
Bueno, espero que os haya sido de utilidad este tutorial.
En Autentia Real Business Solutions, nos gusta compartir el conocimiento. Aquí teneis un poquito más de nuestra aportación.
Si algún día necesitais ayuda con vuestros proyectos o necesitais formación, podéis encontrarnos en Autentia
Carlos García Pérez. Creador de MobileTest, un complemento educativo para los profesores y sus alumnos.
cgpcosmad@gmail.com
Gracias por compartir, lo intentare