Pregunta Cómo usar java.net.URLConnection para abrir y manejar solicitudes HTTP


Uso de java.net.URLConnection se pregunta con bastante frecuencia aquí, y el Tutorial de Oracle es también conciso al respecto.

Ese tutorial básicamente solo muestra cómo activar una solicitud GET y leer la respuesta. No explica en ningún lugar cómo usarlo para, entre otros, realizar una solicitud POST, establecer encabezados de solicitud, leer encabezados de respuesta, tratar con cookies, enviar un formulario HTML, cargar un archivo, etc.

Entonces, ¿cómo puedo usar java.net.URLConnection para disparar y manejar solicitudes HTTP "avanzadas"?


1759


origen


Respuestas:


Primero, un descargo de responsabilidad de antemano: los fragmentos de código publicados son todos ejemplos básicos. Tendrás que manejar triviales IOExceptions y RuntimeExceptiones como NullPointerException, ArrayIndexOutOfBoundsException y se consorte usted mismo.


Preparando

Primero necesitamos saber al menos la URL y el juego de caracteres. Los parámetros son opcionales y dependen de los requisitos funcionales.

String url = "http://example.com";
String charset = "UTF-8";  // Or in Java 7 and later, use the constant: java.nio.charset.StandardCharsets.UTF_8.name()
String param1 = "value1";
String param2 = "value2";
// ...

String query = String.format("param1=%s&param2=%s", 
     URLEncoder.encode(param1, charset), 
     URLEncoder.encode(param2, charset));

Los parámetros de consulta deben estar en name=value formatear y ser concatenado por &. Normalmente también Codificación URL los parámetros de consulta con el juego de caracteres especificado usando URLEncoder#encode().

los String#format() es solo por conveniencia. Prefiero cuando necesitaría el operador de concatenación String + mas de dos veces.


Disparando un HTTP GET solicitud con (opcionalmente) parámetros de consulta

Es una tarea trivial. Es el método de solicitud predeterminado.

URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...

Cualquier cadena de consulta debe concatenarse a la URL usando ?. los Accept-Charset el encabezado puede indicarle al servidor en qué codificación están los parámetros. Si no envía ninguna cadena de consulta, puede dejar el Accept-Charset encabezado de distancia. Si no necesita establecer ningún encabezado, puede incluso usar el URL#openStream() método abreviado.

InputStream response = new URL(url).openStream();
// ...

De cualquier manera, si el otro lado es un HttpServlet, Entonces es doGet() método será llamado y los parámetros estarán disponibles por HttpServletRequest#getParameter().

Para propósitos de prueba, puede imprimir el cuerpo de la respuesta a stdout de la siguiente manera:

try (Scanner scanner = new Scanner(response)) {
    String responseBody = scanner.useDelimiter("\\A").next();
    System.out.println(responseBody);
}

Disparando un HTTP POST solicitud con parámetros de consulta

Configurando el URLConnection#setDoOutput() a true implícitamente establece el método de solicitud en POST. El HTTP POST estándar como lo hacen los formularios web es de tipo application/x-www-form-urlencoded donde la cadena de consulta se escribe en el cuerpo de la solicitud.

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);

try (OutputStream output = connection.getOutputStream()) {
    output.write(query.getBytes(charset));
}

InputStream response = connection.getInputStream();
// ...

Nota: cada vez que desee enviar un formulario HTML mediante programación, no olvide tomar el name=value pares de cualquier <input type="hidden"> elementos en la cadena de consulta y, por supuesto, también el name=value par de la <input type="submit"> Elemento que desea "presionar" mediante programación (porque normalmente se usa en el servidor para distinguir si se presionó un botón y, de ser así, cuál).

También puedes lanzar el obtenido URLConnection a HttpURLConnection y usar su HttpURLConnection#setRequestMethod() en lugar. Pero si intenta usar la conexión para la salida, aún necesita configurar URLConnection#setDoOutput() a true.

HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...

De cualquier manera, si el otro lado es un HttpServlet, Entonces es doPost() método será llamado y los parámetros estarán disponibles por HttpServletRequest#getParameter().


En realidad disparando la solicitud HTTP

Puede disparar la solicitud HTTP explícitamente con URLConnection#connect(), pero la solicitud se activará automáticamente a petición cuando desee obtener información sobre la respuesta HTTP, como el cuerpo de respuesta que utiliza URLConnection#getInputStream()y así. Los ejemplos anteriores hacen exactamente eso, entonces el connect() la llamada es de hecho superflua.


Recopilación de información de respuesta HTTP

  1. Estado de respuesta HTTP:

    Tu necesitas un HttpURLConnection aquí. Echalo primero si es necesario.

    int status = httpConnection.getResponseCode();
    
  2. Encabezados de respuesta HTTP:

    for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
        System.out.println(header.getKey() + "=" + header.getValue());
    }
    
  3. Codificación de respuesta HTTP:

    Cuando el Content-Type contiene una charset parámetro, entonces el cuerpo de la respuesta probablemente esté basado en texto y nos gustaría procesar el cuerpo de la respuesta con la codificación de caracteres especificada en el lado del servidor.

    String contentType = connection.getHeaderField("Content-Type");
    String charset = null;
    
    for (String param : contentType.replace(" ", "").split(";")) {
        if (param.startsWith("charset=")) {
            charset = param.split("=", 2)[1];
            break;
        }
    }
    
    if (charset != null) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(response, charset))) {
            for (String line; (line = reader.readLine()) != null;) {
                // ... System.out.println(line) ?
            }
        }
    } else {
        // It's likely binary content, use InputStream/OutputStream.
    }
    

Mantenimiento de la sesión

La sesión del servidor generalmente está respaldada por una cookie. Algunos formularios web requieren que haya iniciado sesión y / o que una sesión los rastree. Puedes usar el CookieHandler API para mantener las cookies. Necesitas preparar un CookieManager con un CookiePolicy de ACCEPT_ALL antes de enviar todas las solicitudes HTTP.

// First set the default cookie manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

// All the following subsequent URLConnections will use the same cookie manager.
URLConnection connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

Tenga en cuenta que esto se sabe que no siempre funciona correctamente en todas las circunstancias. Si falla para usted, lo mejor es recopilar manualmente y establecer los encabezados de las cookies. Básicamente necesitas agarrar todo Set-Cookie encabezados de la respuesta del inicio de sesión o la primera GET solicitar y luego pasar esto a través de las solicitudes posteriores.

// Gather all cookies on the first request.
URLConnection connection = new URL(url).openConnection();
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
// ...

// Then use the same cookies on all subsequent requests.
connection = new URL(url).openConnection();
for (String cookie : cookies) {
    connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
}
// ...

los split(";", 2)[0] está ahí para deshacerse de los atributos de cookies que son irrelevantes para el lado del servidor como expires, path, etc. Alternativamente, también podrías usar cookie.substring(0, cookie.indexOf(';')) en lugar de split().


Modo de transmisión

los HttpURLConnection por defecto almacenará el búfer todo solicite el cuerpo antes de enviarlo, independientemente de si ha establecido una longitud de contenido fija usted mismo usando connection.setRequestProperty("Content-Length", contentLength);. Esto puede causar OutOfMemoryExceptions siempre que envíe al mismo tiempo solicitudes POST grandes (por ejemplo, carga de archivos). Para evitar esto, le gustaría configurar el HttpURLConnection#setFixedLengthStreamingMode().

httpConnection.setFixedLengthStreamingMode(contentLength);

Pero si la longitud del contenido realmente no se conoce de antemano, puede hacer uso del modo de transmisión en bloque estableciendo el HttpURLConnection#setChunkedStreamingMode() en consecuencia. Esto configurará el HTTP Transfer-Encoding encabezado a chunked lo que obligará al cuerpo de solicitud a enviarse en trozos. El siguiente ejemplo enviará el cuerpo en pedazos de 1 KB.

httpConnection.setChunkedStreamingMode(1024);

Agente de usuario

Puede suceder que una solicitud devuelve una respuesta inesperada, mientras que funciona bien con un navegador web real. El lado del servidor probablemente está bloqueando las solicitudes basadas en User-Agent Encabezado de solicitud los URLConnection lo configurará por defecto Java/1.6.0_19 donde la última parte es obviamente la versión de JRE. Puede anular esto de la siguiente manera:

connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); // Do as if you're using Chrome 41 on Windows 7.

Use la cadena User-Agent de un navegador reciente.


Manejo de errores

Si el código de respuesta HTTP es 4nn (Error de cliente) o 5nn (Error de servidor), entonces es posible que desee leer el HttpURLConnection#getErrorStream() para ver si el servidor ha enviado información de error útil.

InputStream error = ((HttpURLConnection) connection).getErrorStream();

Si el código de respuesta HTTP es -1, entonces algo salió mal con la conexión y el manejo de la respuesta. los HttpURLConnection la implementación está en JREs más antiguos con errores para mantener vivas las conexiones. Es posible que desee desactivarlo configurando el http.keepAlive propiedad del sistema a false. Puede hacer esto programáticamente al comienzo de su aplicación al:

System.setProperty("http.keepAlive", "false");

Subiendo archivos

Normalmente usarías multipart/form-data codificación para contenido POST mixto (datos binarios y de caracteres). La codificación se describe con más detalle en RFC2388.

String param = "value";
File textFile = new File("/path/to/file.txt");
File binaryFile = new File("/path/to/file.bin");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

try (
    OutputStream output = connection.getOutputStream();
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
) {
    // Send normal param.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
    writer.append(CRLF).append(param).append(CRLF).flush();

    // Send text file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"textFile\"; filename=\"" + textFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); // Text file itself must be saved in this charset!
    writer.append(CRLF).flush();
    Files.copy(textFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    Files.copy(binaryFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // End of multipart/form-data.
    writer.append("--" + boundary + "--").append(CRLF).flush();
}

Si el otro lado es un HttpServlet, Entonces es doPost() Se llamará al método y las partes estarán disponibles por HttpServletRequest#getPart() (nota, por lo tanto no  getParameter() ¡y así!). los getPart() Sin embargo, el método es relativamente nuevo, se introdujo en Servlet 3.0 (Glassfish 3, Tomcat 7, etc.). Antes de Servlet 3.0, tu mejor opción es usar Apache Commons FileUpload analizar un multipart/form-data solicitud. Ver también esta respuesta para ejemplos de los enfoques FileUpload y Servelt 3.0.


Tratar con sitios HTTPS desconfiados o no confiables

En ocasiones, debe conectar una URL HTTPS, tal vez porque está escribiendo un raspador web. En ese caso, es probable que enfrente una javax.net.ssl.SSLException: Not trusted server certificate en algunos sitios HTTPS que no mantienen sus certificados SSL actualizados, o java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] found o javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name en algunos sitios HTTPS mal configurados.

El siguiente recorrido de una sola vez static inicializador en su clase de raspador web debe hacer HttpsURLConnection más indulgente en cuanto a esos sitios HTTPS y, por lo tanto, no arrojar esas excepciones más.

static {
    TrustManager[] trustAllCertificates = new TrustManager[] {
        new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null; // Not relevant.
            }
            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
        }
    };

    HostnameVerifier trustAllHostnames = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true; // Just allow them all.
        }
    };

    try {
        System.setProperty("jsse.enableSNIExtension", "false");
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCertificates, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(trustAllHostnames);
    }
    catch (GeneralSecurityException e) {
        throw new ExceptionInInitializerError(e);
    }
}

Ultimas palabras

los Apache HttpComponents HttpClient es mucho más conveniente en todo esto :)


Analizando y extrayendo HTML

Si todo lo que quiere es analizar y extraer datos de HTML, mejor utilice un analizador HTML como Jsoup


2525



Cuando se trabaja con HTTP, casi siempre es más útil referirse a HttpURLConnection en lugar de la clase base URLConnection (ya que URLConnection es una clase abstracta cuando pides URLConnection.openConnection() en una URL HTTP eso es lo que obtendrá de todos modos).

Entonces, en lugar de confiar en URLConnection#setDoOutput(true) para establecer implícitamente el método de solicitud a ENVIAR en lugar de hacer httpURLConnection.setRequestMethod("POST") que algunos podrían encontrar más natural (y que también le permite especificar otros métodos de solicitud como PONER, BORRAR, ...).

También proporciona constantes HTTP útiles para que pueda hacer:

int responseCode = httpURLConnection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

84



Inspirados por esta y otras preguntas sobre SO, he creado una fuente abierta mínima basic-http-client que incorpora la mayoría de las técnicas que se encuentran aquí.

google-http-java-cliente es también un gran recurso de código abierto.


49



Hay 2 opciones que puede elegir con HTTP Hits de URL: GET / POST

Solicitud GET: -

HttpURLConnection.setFollowRedirects(true); // defaults to true

String url = "https://name_of_the_url";
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
System.out.println(String.valueOf(http_conn.getResponseCode()));

Solicitud POST: -

HttpURLConnection.setFollowRedirects(true); // defaults to true

String url = "https://name_of_the_url"
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
http_conn.setDoOutput(true);
PrintWriter out = new PrintWriter(http_conn.getOutputStream());
if (urlparameter != null) {
   out.println(urlparameter);
}
out.close();
out = null;
System.out.println(String.valueOf(http_conn.getResponseCode()));

22



Te sugiero que eches un vistazo al código de kevinsawicki / http-request, básicamente es una envoltura encima de HttpUrlConnection proporciona una API mucho más simple en caso de que desee realizar las solicitudes ahora mismo o puede echar un vistazo a las fuentes (no es demasiado grande) para ver cómo se manejan las conexiones.

Ejemplo: hacer una GET solicitud con tipo de contenido application/json y algunos parámetros de consulta:

// GET http://google.com?q=baseball%20gloves&size=100
String response = HttpRequest.get("http://google.com", true, "q", "baseball gloves", "size", 100)
        .accept("application/json")
        .body();
System.out.println("Response was: " + response);

20



También estaba muy inspirado por esta respuesta.

A menudo estoy en proyectos donde necesito hacer algo de HTTP, y es posible que no quiera incorporar muchas dependencias de terceros (que traen otras, etc., etc.)

Empecé a escribir mis propias utilidades basadas en algunas de estas conversaciones (no en ninguna parte):

package org.boon.utils;


import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

import static org.boon.utils.IO.read;

public class HTTP {

Entonces solo hay un montón o métodos estáticos.

public static String get(
        final String url) {

    Exceptions.tryIt(() -> {
        URLConnection connection;
        connection = doGet(url, null, null, null);
        return extractResponseString(connection);
    });
    return null;
}

public static String getWithHeaders(
        final String url,
        final Map<String, ? extends Object> headers) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, null, null);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

public static String getWithContentType(
        final String url,
        final Map<String, ? extends Object> headers,
        String contentType) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, contentType, null);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}
public static String getWithCharSet(
        final String url,
        final Map<String, ? extends Object> headers,
        String contentType,
        String charSet) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, contentType, charSet);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

Luego publica ...

public static String postBody(
        final String url,
        final String body) {
    URLConnection connection;
    try {
        connection = doPost(url, null, "text/plain", null, body);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

public static String postBodyWithHeaders(
        final String url,
        final Map<String, ? extends Object> headers,
        final String body) {
    URLConnection connection;
    try {
        connection = doPost(url, headers, "text/plain", null, body);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}



public static String postBodyWithContentType(
        final String url,
        final Map<String, ? extends Object> headers,
        final String contentType,
        final String body) {

    URLConnection connection;
    try {
        connection = doPost(url, headers, contentType, null, body);


        return extractResponseString(connection);


    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }


}


public static String postBodyWithCharset(
        final String url,
        final Map<String, ? extends Object> headers,
        final String contentType,
        final String charSet,
        final String body) {

    URLConnection connection;
    try {
        connection = doPost(url, headers, contentType, charSet, body);


        return extractResponseString(connection);


    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }


}

private static URLConnection doPost(String url, Map<String, ? extends Object> headers,
                                    String contentType, String charset, String body
                                    ) throws IOException {
    URLConnection connection;/* Handle output. */
    connection = new URL(url).openConnection();
    connection.setDoOutput(true);
    manageContentTypeHeaders(contentType, charset, connection);

    manageHeaders(headers, connection);


    IO.write(connection.getOutputStream(), body, IO.CHARSET);
    return connection;
}

private static void manageHeaders(Map<String, ? extends Object> headers, URLConnection connection) {
    if (headers != null) {
        for (Map.Entry<String, ? extends Object> entry : headers.entrySet()) {
            connection.setRequestProperty(entry.getKey(), entry.getValue().toString());
        }
    }
}

private static void manageContentTypeHeaders(String contentType, String charset, URLConnection connection) {
    connection.setRequestProperty("Accept-Charset", charset == null ? IO.CHARSET : charset);
    if (contentType!=null && !contentType.isEmpty()) {
        connection.setRequestProperty("Content-Type", contentType);
    }
}

private static URLConnection doGet(String url, Map<String, ? extends Object> headers,
                                    String contentType, String charset) throws IOException {
    URLConnection connection;/* Handle output. */
    connection = new URL(url).openConnection();
    manageContentTypeHeaders(contentType, charset, connection);

    manageHeaders(headers, connection);

    return connection;
}

private static String extractResponseString(URLConnection connection) throws IOException {
/* Handle input. */
    HttpURLConnection http = (HttpURLConnection)connection;
    int status = http.getResponseCode();
    String charset = getCharset(connection.getHeaderField("Content-Type"));

    if (status==200) {
        return readResponseBody(http, charset);
    } else {
        return readErrorResponseBody(http, status, charset);
    }
}

private static String readErrorResponseBody(HttpURLConnection http, int status, String charset) {
    InputStream errorStream = http.getErrorStream();
    if ( errorStream!=null ) {
        String error = charset== null ? read( errorStream ) :
            read( errorStream, charset );
        throw new RuntimeException("STATUS CODE =" + status + "\n\n" + error);
    } else {
        throw new RuntimeException("STATUS CODE =" + status);
    }
}

private static String readResponseBody(HttpURLConnection http, String charset) throws IOException {
    if (charset != null) {
        return read(http.getInputStream(), charset);
    } else {
        return read(http.getInputStream());
    }
}

private static String getCharset(String contentType) {
    if (contentType==null)  {
        return null;
    }
    String charset = null;
    for (String param : contentType.replace(" ", "").split(";")) {
        if (param.startsWith("charset=")) {
            charset = param.split("=", 2)[1];
            break;
        }
    }
    charset = charset == null ?  IO.CHARSET : charset;

    return charset;
}

Bueno, ya captas la idea....

Aquí están las pruebas:

static class MyHandler implements HttpHandler {
    public void handle(HttpExchange t) throws IOException {

        InputStream requestBody = t.getRequestBody();
        String body = IO.read(requestBody);
        Headers requestHeaders = t.getRequestHeaders();
        body = body + "\n" + copy(requestHeaders).toString();
        t.sendResponseHeaders(200, body.length());
        OutputStream os = t.getResponseBody();
        os.write(body.getBytes());
        os.close();
    }
}


@Test
public void testHappy() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9212), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBodyWithContentType("http://localhost:9212/test", headers, "text/plain", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));


    response = HTTP.postBodyWithCharset("http://localhost:9212/test", headers, "text/plain", "UTF-8", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    response = HTTP.postBodyWithHeaders("http://localhost:9212/test", headers, "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));


    response = HTTP.get("http://localhost:9212/test");

    System.out.println(response);


    response = HTTP.getWithHeaders("http://localhost:9212/test", headers);

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));



    response = HTTP.getWithContentType("http://localhost:9212/test", headers, "text/plain");

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));



    response = HTTP.getWithCharSet("http://localhost:9212/test", headers, "text/plain", "UTF-8");

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    Thread.sleep(10);

    server.stop(0);


}

@Test
public void testPostBody() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9220), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBody("http://localhost:9220/test", "hi mom");

    assertTrue(response.contains("hi mom"));


    Thread.sleep(10);

    server.stop(0);


}

@Test(expected = RuntimeException.class)
public void testSad() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9213), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBodyWithContentType("http://localhost:9213/foo", headers, "text/plain", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    Thread.sleep(10);

    server.stop(0);


}

Puedes encontrar el resto aqui:

https://github.com/RichardHightower/boon

Mi objetivo es proporcionar las cosas comunes que uno querría hacer de una manera un poco más fácil que ...


19



Actualizar

El nuevo cliente HTTP incluido con Java 9 pero como parte de un   Módulo de incubadora llamado jdk.incubator.httpclient. Los módulos de la incubadora son   un medio para poner API no finales en manos de desarrolladores mientras el   Las API avanzan hacia la finalización o eliminación en un futuro   lanzamiento.

En Java 9, puede enviar un GET solicitud como:

// GET
HttpResponse response = HttpRequest
    .create(new URI("http://www.stackoverflow.com"))
    .headers("Foo", "foovalue", "Bar", "barvalue")
    .GET()
    .response();

Luego puede examinar el resultado HttpResponse:

int statusCode = response.statusCode();
String responseBody = response.body(HttpResponse.asString());

Dado que este nuevo cliente HTTP está en java.httpclient  jdk.incubator.httpclient módulo, debe declarar esta dependencia en su module-info.java archivo:

module com.foo.bar {
    requires jdk.incubator.httpclient;
}

15