Comment utiliser java.net.URLConnection pour lancer et traiter les requêtes HTTP

utilisation de java.net.URLConnection est assez souvent demandé sur ici, et le tutoriel Oracle est trop concis à ce sujet.

ce tutoriel ne montre que comment lancer une requête GET et lire la réponse. Il n'explique nulle part comment l'utiliser pour, entre autres, effectuer une requête POST, définir les en-têtes de requête, lire les en-têtes de réponse, traiter les cookies, soumettre un formulaire HTML, télécharger un fichier, etc.

alors, comment puis-je utiliser java.net.URLConnection pour lancer et traiter des requêtes HTTP" avancées"?

1780
demandé sur BalusC 2010-05-08 10:16:11

11 réponses

tout d'abord un avertissement préalable: les extraits de code affichés sont tous des exemples de base. Vous aurez besoin de gérer trivial IOException s et RuntimeException s comme NullPointerException , ArrayIndexOutOfBoundsException et consorts vous-même.


préparation

nous avons d'abord besoin de connaître au moins L'URL et le jeu de caractères. Les paramètres sont optionnels et dépendent de la fonctionnalité exigence.

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));

les paramètres de la requête doivent être au format name=value et être concaténés par & . Vous devriez normalement aussi URL-Encoder les paramètres de requête avec le jeu de caractères spécifié en utilisant URLEncoder#encode() .

le String#format() est juste pour la commodité. Je préfère quand j'aurais besoin de l'opérateur de concaténation de Chaîne + plus de deux fois.


"15191020920 de" Cuisson HTTP GET demande avec (éventuellement) les paramètres de la requête

c'est une tâche insignifiante. C'est la méthode de requête par défaut.

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

toute chaîne de requête doit être concaténée à L'URL en utilisant ? . L'en-tête Accept-Charset peut indiquer au serveur l'encodage des paramètres. Si vous n'envoyez pas de n'importe quelle chaîne de requête, alors vous pouvez laisser l'en-tête Accept-Charset loin. Si vous n'avez pas besoin de définir des en-têtes, vous pouvez même utiliser la méthode de raccourci URL#openStream() .

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

dans les deux cas, si l'autre partie est une HttpServlet , alors sa méthode doGet() sera appelée et les paramètres seront disponibles par HttpServletRequest#getParameter() .

pour des raisons de test, vous pouvez imprimer le corps de réponse à stdout comme ci-dessous:

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

"15191020920 de" Cuisson HTTP POST demande avec les paramètres de la requête

définir la URLConnection#setDoOutput() à true définit implicitement la méthode de requête à afficher. Le POST HTTP standard comme le font les formulaires web est de type application/x-www-form-urlencoded où la chaîne de requête est écrite à la corps de la requête.

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();
// ...

Note: chaque fois que vous souhaitez soumettre un formulaire HTML par programmation, n'oubliez pas de prendre les paires name=value de n'importe quels éléments <input type="hidden"> dans la chaîne de requête et bien sûr aussi la paire name=value de l'élément <input type="submit"> que vous souhaitez" presser " par programmation (parce que c'est habituellement utilisé dans le côté serveur pour distinguer si un bouton a été pressé et si oui, lequel).

vous pouvez aussi mouler le URLConnection à HttpURLConnection et utiliser son HttpURLConnection#setRequestMethod() à la place. Mais si vous essayez d'utiliser la connexion pour la sortie, vous devez encore définir des URLConnection#setDoOutput() à true .

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

dans les deux cas, si l'autre partie est une HttpServlet , puis son doPost() méthode sera appelée avec les paramètres seront disponibles par HttpServletRequest#getParameter() .


mise à feu effective de la requête HTTP

vous pouvez lancer la requête HTTP explicitement avec URLConnection#connect() , mais la requête sera automatiquement lancée à la demande lorsque vous voulez obtenir des informations sur la réponse HTTP, comme le corps de la réponse en utilisant URLConnection#getInputStream() et ainsi de suite. Les exemples ci-dessus font exactement cela, de sorte que l'appel connect() est en fait superflu.


collecting HTTP response information

  1. statut de la réponse HTTP :

    vous avez besoin d'un HttpURLConnection ici. Il la jeta d'abord si nécessaire.

    int status = httpConnection.getResponseCode();
    
  2. en-têtes de réponse HTTP :

    for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
        System.out.println(header.getKey() + "=" + header.getValue());
    }
    
  3. réponse HTTP encoding :

    lorsque le Content-Type contient un paramètre charset , alors le corps de réponse est probablement basé sur du texte et nous aimerions traiter le corps de réponse avec le codage de caractères spécifié côté serveur.

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

le Maintien de la session

la session côté serveur est généralement sauvegardée par un cookie. Certains formulaires web exigent que vous êtes connecté et/ou sont suivis par une séance. Vous pouvez utiliser L'API CookieHandler pour maintenir les cookies. Vous devez préparer un CookieManager avec un CookiePolicy de ACCEPT_ALL avant d'envoyer toutes les requêtes 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();
// ...

noter que cela ne fonctionne pas toujours correctement dans toutes les circonstances. Si elle échoue pour vous, alors le mieux est de rassembler manuellement et de définir les en-têtes de cookie. Vous avez essentiellement besoin de saisir tous les en-têtes Set-Cookie de la réponse de la connexion ou de la première demande GET et puis passer à travers les requêtes suivantes.

// 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]);
}
// ...

Le split(";", 2)[0] est là pour se débarrasser de les attributs de cookies qui ne sont pas pertinents du côté du serveur comme expires , path , etc. Vous pouvez également utiliser cookie.substring(0, cookie.indexOf(';')) au lieu de split() .


mode de diffusion en continu

le HttpURLConnection amortira par défaut le corps de requête entier avant de l'envoyer, que vous ayez ou non défini vous-même une longueur de contenu fixe en utilisant connection.setRequestProperty("Content-Length", contentLength); . Cela peut causer OutOfMemoryException s chaque fois que vous envoyez simultanément de grandes requêtes POST (par exemple, le téléchargement de fichiers). Pour éviter cela, vous souhaitez HttpURLConnection#setFixedLengthStreamingMode() .

httpConnection.setFixedLengthStreamingMode(contentLength);

mais si la longueur du contenu n'est vraiment pas connue au préalable, vous pouvez utiliser le mode de diffusion en continu en réglant le HttpURLConnection#setChunkedStreamingMode() en conséquence. Cela définira le HTTP Transfer-Encoding en-tête chunked qui va forcer le corps de la requête envoyée en morceaux. L'exemple ci-dessous enverra le corps en morceaux de 1KB.

httpConnection.setChunkedStreamingMode(1024);

User-Agent

Il peut arriver que des une requête retourne une réponse inattendue, alors qu'il fonctionne très bien avec un vrai navigateur web . Le côté serveur bloque probablement les requêtes basées sur le User-Agent en-tête de requête. Le URLConnection le définira par défaut à Java/1.6.0_19 où la dernière partie est évidemment la version JRE. Vous pouvez modifier ceci comme suit:

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.

utilisez la chaîne User-Agent d'un navigateur récent .


traitement des erreurs

si le code de réponse HTTP est 4nn (erreur du Client) ou 5nn (erreur du serveur)), vous pouvez alors lire le HttpURLConnection#getErrorStream() pour voir si le serveur a envoyé des informations d'erreur utiles.

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

si le code de réponse HTTP est -1, alors quelque chose a mal tourné avec la gestion de la connexion et de la réponse. La mise en œuvre de HttpURLConnection est dans les JREs plus anciennes un peu buggée avec garder les connexions vivantes. Vous pouvez désactiver cette option en paramétrant la propriété de système http.keepAlive à false . Vous pouvez le faire programmatiquement au début de votre demande de:

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

Téléchargement de fichiers

vous devez normalement utiliser multipart/form-data encodage pour un contenu Post mixte (données binaires et de caractères). Le codage est décrit plus en détail dans 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 l'autre partie est une HttpServlet , puis son doPost() La méthode sera appelée et les pièces seront disponibles par HttpServletRequest#getPart() (note, donc pas getParameter() et ainsi de suite!). La méthode getPart() est cependant relativement nouvelle, elle est introduite dans le Servlet 3.0 (Glassfish 3, Tomcat 7, etc). Avant Servlet 3.0, votre meilleur choix est d'utiliser Apache Commons FileUpload pour analyser une requête multipart/form-data . Voir aussi cette réponse pour exemples des approches FileUpload et Servelt 3.0.


Traiter avec douteuses ou mal configuré les sites HTTPS

parfois, vous devez connecter une URL HTTPS, peut-être parce que vous écrivez un scraper web. Dans ce cas, vous pourriez être confronté à un javax.net.ssl.SSLException: Not trusted server certificate sur certains sites HTTPS qui ne tiennent pas leurs certificats SSL à jour, ou à un java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] found ou javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name sur certains sites HTTPS mal configurés.

l'initialiseur unique static suivant dans votre classe de grattoir web devrait rendre HttpsURLConnection plus clément quant à ces sites HTTPS et donc ne plus jeter ces exceptions.

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);
    }
}

derniers mots

Le Apache HttpComponents HttpClient est beaucoup plus pratique dans tout cela :)


l'Analyse et l'extraction HTML

si tout ce que vous voulez est l'analyse et l'extraction de données à partir de HTML, alors mieux utiliser un analyseur HTML comme Jsoup

2552
répondu BalusC 2018-07-26 12:14:04

lorsque vous travaillez avec HTTP, il est presque toujours plus utile de faire référence à HttpURLConnection plutôt qu'à la classe de base URLConnection (puisque URLConnection est une classe abstraite quand vous demandez URLConnection.openConnection() sur une URL HTTP qui est ce que vous obtiendrez de toute façon).

alors vous pouvez au lieu de compter sur URLConnection#setDoOutput(true) pour implicitement définir la méthode de requête à POST au lieu de faire httpURLConnection.setRequestMethod("POST") que certains pourraient trouver plus naturel (et qui vous permet également de spécifier d'autres méthodes de requête telles que PUT , DELETE , ...).

il fournit également des constantes HTTP utiles de sorte que vous pouvez le faire:

int responseCode = httpURLConnection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {
86
répondu Paal Thorstensen 2013-12-17 00:24:55

inspiré par ceci et d'autres questions sur SO, j'ai créé un open source minimal basic-http-client qui incarne la plupart des techniques trouvées ici.

google-http-java-client est aussi un grand open source de ressources.

49
répondu David Chandler 2012-06-13 16:37:47

il y a 2 options que vous pouvez utiliser avec les URL Hits HTTP: GET /POST

GET 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);
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
répondu Utkash Bhatt 2017-05-05 16:40:31

je vous suggère de jeter un coup d'oeil au code sur kevinsawicki/requête http , c'est essentiellement un wrapper en haut de HttpUrlConnection il fournit une API beaucoup plus simple au cas où vous voulez juste faire les requêtes maintenant ou vous pouvez jeter un oeil aux sources (ce n'est pas trop grand) pour jeter un oeil à la façon dont les connexions sont traitées.

exemple: faire une requête GET avec le type de contenu application/json et quelques paramètres de requête:

// 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
répondu fernandohur 2014-11-24 13:43:51

j'ai été très inspiré par cette réponse.

je suis souvent sur des projets où j'ai besoin de faire un peu de HTTP, et je ne veux peut-être pas apporter beaucoup de dépendances de tiers (qui apportent d'autres et ainsi de suite et ainsi de suite, etc.)

j'ai commencé à écrire mes propres utilitaires basés sur une partie de cette conversation (pas n'importe où fait):

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 {

puis il y a juste un tas ou des méthodes statiques.

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;
    }
}

puis postez...

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;
}

Eh bien, vous comprenez l'idée....

Voici les épreuves:

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);


}

vous pouvez trouver le reste ici:

https://github.com/RichardHightower/boon

mon but est de fournir les choses communes que l'on voudrait faire d'une manière un peu plus facile alors....

19
répondu RickHigh 2013-10-17 05:35:17

mise à Jour

le nouveau Client HTTP livré avec Java 9 mais dans le cadre d'un Module d'incubateur nommé jdk.incubator.httpclient . Les modules d'incubateur sont: un moyen de mettre les API non-finales dans les mains des développeurs tandis que le Api progrès vers soit de finalisation ou de retrait, dans un avenir publier.

en Java 9, Vous pouvez envoyer une GET demande comme:

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

alors vous pouvez examinez le retour HttpResponse :

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

puisque ce nouveau Client HTTP est java.httpclient jdk.incubator.httpclient module, vous devez déclarer cette dépendance dans votre fichier module-info.java :

module com.foo.bar {
    requires jdk.incubator.httpclient;
}
16
répondu Ali Dehghani 2017-11-30 15:16:39

au départ, j'ai été induit en erreur par cet article qui favorise HttpClient .

plus tard, j'ai été réalisé que HttpURLConnection va rester de ce article

comme sur le Blog de Google :

le client HTTP Apache a moins de bogues sur Eclair et Froyo. C'est le meilleur choix pour ces versions. Pour Le Pain D'Épice, HttpURLConnection est le meilleur choix. Son API simple et de petite taille le rend idéal pour Android.

compression transparente et Cache réponse réduire l'utilisation du réseau, améliorer la vitesse et économiser la batterie. Les nouvelles applications devraient utiliser HttpURLConnection; c'est là que nous dépenserons notre énergie à l'avenir.

après avoir lu cet article et quelques autres questions sur la pile sur l'écoulement, je suis convaincu que HttpURLConnection va rester pour de plus longues durées.

certaines de ces questions favorisant HttpURLConnections :

sur Android, faire une demande de poste avec des données de forme encodées URL sans utiliser UrlEncodedFormEntity

HttpPost travaille dans le projet Java, pas dans Android

14
répondu Ravindra babu 2017-05-23 11:55:13

vous pouvez également utiliser JdkRequest de jcabi-http "http (je suis développeur), qui fait tout ce travail pour vous, décorer HttpURLConnection, lancer des requêtes HTTP et analyser les réponses, par exemple:

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

voir ce billet de blog pour plus d'informations: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

11
répondu yegor256 2014-04-11 18:54:16

il y a aussi OkHttp , qui est un client HTTP efficace par défaut:

  • le support HTTP/2 permet à toutes les requêtes vers le même hôte de partager une socket.
  • pooling de Connexion réduit la demande de latence (si HTTP/2 n'est pas disponible).
  • Transparent GZIP se rétrécit en taille de téléchargement.
  • la mise en cache de la réponse évite le réseau complètement pour les demandes répétées.

créer D'abord une instance de OkHttpClient :

OkHttpClient client = new OkHttpClient();

alors, préparez votre GET demande:

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

enfin, utiliser OkHttpClient pour envoyer Request :

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

pour plus de détails, vous pouvez consulter la documentation D'OkHttp

11
répondu Ali Dehghani 2016-01-15 12:06:33

si vous utilisez http get s'il vous plaît supprimer cette ligne

urlConnection.setDoOutput(true);
10
répondu Nison Cheruvathur 2017-12-20 07:15:18