Cómo utilizar java.net.URLConnection para disparar y manejar las peticiones HTTP


Uso de java.net.URLConnection se le pregunta acerca bastante a menudo aquí, y el Oracle tutorial es demasiado conciso al respecto.

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

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

Author: BalusC, 2010-05-08

11 answers

Primero una advertencia de antemano: los fragmentos de código publicados son todos ejemplos básicos. Usted tendrá que manejar trivial IOException s y RuntimeException s como NullPointerException, ArrayIndexOutOfBoundsException y se consuela.


Preparando

Primero necesitamos saber al menos la URL y el conjunto 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 formato name=value y estar concatenados por &. Normalmente también URL-codifica los parámetros de consulta con el conjunto de caracteres especificado usando URLEncoder#encode().

El String#format() es solo por conveniencia. Lo prefiero cuando necesitaría el operador de concatenación de cadenas + más de dos veces.


Disparando una solicitud HTTP GET 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 ser concatenada a la URL usando ?. Las Accept-Charset el encabezado puede indicar al servidor en qué codificación se encuentran los parámetros. Si no envía ninguna cadena de consulta, entonces puede dejar el encabezado Accept-Charset lejos. Si no necesita establecer ningún encabezado, incluso puede usar el URL#openStream() método de acceso directo.

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

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

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

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

Disparando una solicitud HTTP POST con parámetros de consulta

Estableciendo el URLConnection#setDoOutput() to true establece implícitamente el método de solicitud para POST. El HTTP POST estándar como lo hacen los formularios web es de tipo application/x-www-form-urlencoded en el que 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: siempre que desee enviar un formulario HTML mediante programación, no olvide tomar los pares name=value de cualquier elemento <input type="hidden"> en la cadena de consulta y, por supuesto, también el par name=value del elemento <input type="submit"> que le gustaría "presionar" programáticamente (porque generalmente se usa en el lado del servidor para distinguir si se presionó un botón y, de ser así, cuál).

También puede lanzar el obtenido URLConnection to HttpURLConnection y utilizar su HttpURLConnection#setRequestMethod() en su lugar. Pero si está tratando de usar la conexión para la salida, aún debe configurar URLConnection#setDoOutput() to true.

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

, de cualquier manera, si el otro lado es un HttpServlet, luego de su 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 cuando desee obtener información sobre la respuesta HTTP, como el cuerpo de la respuesta que utiliza URLConnection#getInputStream() y así sucesivamente. Los ejemplos anteriores hacen exactamente eso, por lo que la llamada connect() es de hecho superflua.


Recopilación de información de respuesta HTTP

  1. Estado de la respuesta HTTP :

    Se necesita un HttpURLConnection aquí. Lanzarlo 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 un parámetro charset, 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 lado del servidor generalmente está respaldada por una cookie. Algunos formularios web requieren que haya iniciado sesión y / o que una sesión lo rastree. Puede utilizar el CookieHandler API para mantener las cookies. Usted necesita preparar un CookieManager con a 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 se sabe que esto no siempre funciona correctamente en todas las circunstancias. Si falla para usted, entonces lo mejor es recopilar y configurar manualmente los encabezados de las cookies. Básicamente necesita tomar todos los encabezados Set-Cookie de la respuesta del inicio de sesión o la primera solicitud GET 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]);
}
// ...

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


Modo de transmisión

El HttpURLConnection almacenará de forma predeterminada el cuerpo de la solicitud antes de enviarla, independientemente de si ha establecido una longitud de contenido fija usted mismo usando connection.setRequestProperty("Content-Length", contentLength);. Esto puede causar OutOfMemoryException s siempre que simultáneamente envíe grandes solicitudes POST (por ejemplo, cargando archivos). Para evitar esto, le gustaría establecer el HttpURLConnection#setFixedLengthStreamingMode().

httpConnection.setFixedLengthStreamingMode(contentLength);

Pero si la longitud del contenido realmente no se conoce de antemano, entonces puede hacer uso del modo de transmisión fragmentada configurando el HttpURLConnection#setChunkedStreamingMode() en consecuencia. Esto establecerá el HTTP Transfer-Encoding header a chunked que forzará que el cuerpo de la solicitud se envíe en trozos. El siguiente ejemplo enviará el cuerpo en trozos de 1KB.

httpConnection.setChunkedStreamingMode(1024);

Agente de usuario

Puede suceder que una solicitud devuelva 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. El URLConnection lo establecerá por defecto en 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.

Utilice la cadena User-Agent de un navegador reciente .


Manejo de errores

Si el código de respuesta HTTP es 4nn (Error del Cliente) o 5nn (Error del Servidor), entonces puede desea leer el HttpURLConnection#getErrorStream() para ver si el servidor ha enviado alguna 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. La implementación de HttpURLConnection está en JREs más antiguos algo defectuosa y mantiene las conexiones vivas. Es posible que desee desactivarlo estableciendo la propiedad del sistema http.keepAlive a false. Puede hacer esto programáticamente al principio de su aplicación:

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

Cargando files

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, luego de su doPost() método será llamado y las partes estarán disponibles por HttpServletRequest#getPart() (nota, por lo tanto no getParameter() y así sucesivamente!). Sin embargo, el método getPart() es relativamente nuevo, se introdujo en Servlet 3.0 (Glassfish 3, Tomcat 7, etc.). Antes de Servlet 3.0, su mejor opción es usar Apache Commons FileUpload para analizar una solicitud multipart/form-data. Ver también esta respuesta para ejemplos de los enfoques FileUpload y Servelt 3.0.


Tratar con sitios HTTPS no confiables o mal configurados

A veces necesitas conectar una URL HTTPS, quizás porque estás escribiendo un web scraper. En ese caso, es probable que se enfrente a un javax.net.ssl.SSLException: Not trusted server certificate en algunos sitios HTTPS que no mantiene sus certificados SSL actualizados, o un 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 inicializador de una sola vez static en su clase web scraper debería hacer a HttpsURLConnection más indulgente en cuanto a esos sitios HTTPS y, por lo tanto, no lanzar 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);
    }
}

Últimas palabras

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


Analizar y extraer HTML

Si todo lo que desea es analizar y extraer datos de HTML, entonces es mejor usar un analizador HTML como Jsoup

 2552
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-26 12:14:04

Cuando se trabaja con HTTP es casi siempre más útil referirse a HttpURLConnection en lugar de la clase base URLConnection (ya que URLConnection es una clase abstracta cuando se pide URLConnection.openConnection() en una URL HTTP que 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 POST 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 PUT, SUPRÍMASE , ...).

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

int responseCode = httpURLConnection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {
 86
Author: Paal Thorstensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-17 00:24:55

Inspirado por esta y otras preguntas sobre SO, he creado un código abierto mínimo basic-http-client que encarna la mayoría de las técnicas que se encuentran aquí.

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

 49
Author: David Chandler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-13 16:37:47

Hay 2 opciones que puede ir con HTTP URL Hits: 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()));

POST request: -

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
Author: Utkash Bhatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-05 16:40:31

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

Ejemplo: Haga una solicitud GET con el 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
Author: fernandohur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-24 13:43:51

También me sentí muy inspirado por esta respuesta.

A menudo estoy en proyectos donde necesito hacer algo de HTTP, y puede que no quiera traer muchas dependencias de terceros (que traen otros, etc., etc.).)

Comencé a escribir mis propias utilidades basadas en parte de esta conversación (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 hay solo 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;
    }
}

Entonces post...

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 tienes la idea....

Aquí están los 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 aquí:

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

 19
Author: RickHigh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-17 05:35:17

Actualizar

El nuevo cliente HTTP enviado con Java 9 pero como parte de un Módulo de incubadora llamado jdk.incubator.httpclient. Los módulos de incubadora son un medio de poner las API no finales en manos de los desarrolladores, mientras que el El progreso de las API hacia la finalización o eliminación en un futuro lanzar.

En Java 9, puede enviar una solicitud GET como:

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

Luego puedes examinar el HttpResponse devuelto:

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

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

module com.foo.bar {
    requires jdk.incubator.httpclient;
}
 16
Author: Ali Dehghani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 15:16:39

Inicialmente me engañó este artículo que favorece HttpClient.

Más tarde me he dado cuenta de que HttpURLConnection se va a quedar de este artículo

Según el blog de Google :

El cliente HTTP Apache tiene menos errores en Eclair y Froyo. Es la mejor opción para estos lanzamientos. Para el pan de jengibre , HttpURLConnection es la mejor opción. Su sencilla API y su pequeño tamaño lo hacen ideal para Android.

Compresión transparente y el almacenamiento en caché de respuesta reduce el uso de la red, mejora la velocidad y ahorra batería. Las nuevas aplicaciones deben utilizar HttpURLConnection; es donde vamos a gastar nuestra energía en el futuro.

Después de leer este artículo y algunas otras preguntas de stack over flow, estoy convencido de que HttpURLConnection se va a quedar por períodos más largos.

Algunas de las preguntas SE favoreciendo HttpURLConnections:

En Android, realiza una solicitud POST con datos de formulario codificados en URL sin usar UrlEncodedFormEntity

HttpPost funciona en Java project, no en Android

 14
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:13

También puede utilizar JdkRequest desde jcabi-http (soy un desarrollador), que hace todo este trabajo por ti, decorando HttpURLConnection, disparando solicitudes HTTP y analizando respuestas, por ejemplo:

String html = new JdkRequest("http://www.google.com").fetch().body();

Revisa esta entrada del blog para más información: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

 11
Author: yegor256,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-11 18:54:16

También está OkHttp , que es un cliente HTTP que es eficiente por defecto:

  • El soporte HTTP/2 permite que todas las solicitudes al mismo host compartan un socket.
  • La agrupación de conexiones reduce la latencia de la solicitud (si HTTP/2 no está disponible).
  • El GZIP transparente reduce el tamaño de las descargas.
  • El almacenamiento en caché de respuestas evita completamente la red para solicitudes repetidas.

Primero crea una instancia de OkHttpClient:

OkHttpClient client = new OkHttpClient();

Luego, prepare su GET solicitud:

Request request = new Request.Builder()
      .url(url)
      .build();

Finalmente, use OkHttpClient para enviar preparado Request:

Response response = client.newCall(request).execute();

Para más detalles, puede consultar la documentación de OkHttp

 11
Author: Ali Dehghani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-15 12:06:33

Si está utilizando http get, elimine esta línea

urlConnection.setDoOutput(true);
 10
Author: Nison Cheruvathur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-20 07:15:18