Come utilizzare java. net. URLConnection per attivare e gestire le richieste HTTP


Uso di java.net.URLConnection viene chiesto abbastanza spesso qui, e il Oracle tutorial è troppo conciso su di esso.

Questo tutorial mostra fondamentalmente solo come attivare una richiesta GET e leggere la risposta. Non spiega da nessuna parte come usarlo per eseguire tra l'altro una richiesta POST, impostare le intestazioni delle richieste, leggere le intestazioni delle risposte, gestire i cookie, inviare un modulo HTML, caricare un file, ecc.

Quindi, come posso usare java.net.URLConnection per attivare e gestire HTTP "avanzato" richieste?

Author: BalusC, 2010-05-08

11 answers

Prima un disclaimer in anticipo: i frammenti di codice pubblicati sono tutti esempi di base. Dovrai gestire banali IOExceptions e RuntimeExceptions come NullPointerException, ArrayIndexOutOfBoundsException e consorti te stesso.


Preparazione

Dobbiamo prima conoscere almeno l'URL e il set di caratteri. I parametri sono opzionali e dipendono dai requisiti funzionali.

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

I parametri della query devono essere nel formato name=value ed essere concatenati da &. Si farebbe normalmente anche URL-encode i parametri della query con il set di caratteri specificato utilizzando URLEncoder#encode().

Il String#format() è solo per comodità. Lo preferisco quando avrei bisogno dell'operatore di concatenazione delle stringhe + più di due volte.


Attivazione di una richiesta HTTP GET con (facoltativamente) parametri di query

È un compito banale. È il metodo di richiesta predefinito.

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

Qualsiasi stringa di query deve essere concatenata all'URL utilizzando ?. Il Accept-Charset l'intestazione può suggerire al server in quale codifica si trovano i parametri. Se non si invia alcuna stringa di query, è possibile lasciare l'intestazione Accept-Charset. Se non è necessario impostare alcuna intestazione, è anche possibile utilizzare URL#openStream() metodo di scelta rapida.

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

In entrambi i casi, se l'altro lato è un HttpServlet, poi la sua doGet() il metodo verrà chiamato e i parametri saranno disponibili da HttpServletRequest#getParameter().

Per il test per scopi, è possibile stampare il corpo della risposta su stdout come di seguito:

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

Attivazione di una richiesta HTTP POST con parametri di query

Impostazione del URLConnection#setDoOutput() a true imposta implicitamente il metodo di richiesta su POST. Il POST HTTP standard come fanno i moduli Web è di tipo application/x-www-form-urlencoded in cui la stringa di query viene scritta nel corpo della richiesta.

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: ogni volta che si desidera inviare un modulo HTML a livello di codice, non dimenticare di prendere le coppie name=value di qualsiasi <input type="hidden"> elementi nella stringa di query e, naturalmente, anche la coppia name=value dell'elemento <input type="submit"> che si desidera "premere" a livello di codice (perché di solito è stato utilizzato nel lato server per distinguere se è stato premuto un pulsante e, in tal caso, quale).

Puoi anche lanciare il risultato ottenuto URLConnection a HttpURLConnection e usa il suo HttpURLConnection#setRequestMethod() invece. Ma se stai cercando di utilizzare la connessione per l'output devi comunque impostare URLConnection#setDoOutput() a true.

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

In entrambi i casi, se l'altro lato è un HttpServlet, poi la sua doPost() il metodo verrà chiamato e i parametri saranno disponibili da HttpServletRequest#getParameter().


Attiva effettivamente la richiesta HTTP

È possibile attivare esplicitamente la richiesta HTTP con URLConnection#connect(), ma la richiesta verrà automaticamente attivata su richiesta quando si desidera ottenere informazioni sulla risposta HTTP, ad esempio il corpo della risposta utilizzando URLConnection#getInputStream() e così via. Gli esempi precedenti fanno esattamente questo, quindi la chiamata connect() è in realtà superflua.


Raccolta di informazioni sulla risposta HTTP

  1. Stato della risposta HTTP:

    Hai bisogno di un HttpURLConnection tieni. Lanciare prima se necessario.

    int status = httpConnection.getResponseCode();
    
  2. Intestazioni di risposta HTTP:

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

    Quando il Content-Type contiene un parametro charset, quindi il corpo della risposta è probabilmente basato sul testo e vorremmo elaborare il corpo della risposta con la codifica dei caratteri specificata sul lato server.

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

Mantenimento della sessione

La sessione lato server è solitamente supportata da un cookie. Alcuni moduli Web richiedono che tu abbia effettuato l'accesso e/o che tu sia monitorato da una sessione. È possibile utilizzare il CookieHandler API per mantenere i cookie. È necessario preparare un CookieManager con un CookiePolicy di ACCEPT_ALL prima di inviare tutte le richieste 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();
// ...

Si noti che questo è noto per non funzionare sempre correttamente in tutte le circostanze. Se fallisce per te, allora la cosa migliore è raccogliere e impostare manualmente le intestazioni dei cookie. Fondamentalmente è necessario afferrare tutte le intestazioni Set-Cookie dalla risposta del login o dalla prima richiesta GET e quindi passare attraverso le richieste successive.

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

Il {[61] } è lì per sbarazzarsi degli attributi dei cookie che sono irrilevante per il lato server come expires, path, ecc. In alternativa, puoi anche usare cookie.substring(0, cookie.indexOf(';')) invece di split().


Modalità streaming

Il HttpURLConnection per impostazione predefinita buffer l'intero corpo della richiesta prima di inviarlo effettivamente, indipendentemente dal fatto che tu abbia impostato una lunghezza di contenuto fissa usando connection.setRequestProperty("Content-Length", contentLength);. Ciò può causare OutOfMemoryExceptions ogni volta che si inviano contemporaneamente richieste POST di grandi dimensioni (ad esempio il caricamento di file). Per evitare questo, si desidera impostare il HttpURLConnection#setFixedLengthStreamingMode().

httpConnection.setFixedLengthStreamingMode(contentLength);

Ma se la lunghezza del contenuto non è nota in anticipo, è possibile utilizzare la modalità di streaming chunked impostando HttpURLConnection#setChunkedStreamingMode() di conseguenza. Questo imposterà il HTTP Transfer-Encoding intestazione a chunked che costringerà il corpo della richiesta a essere inviato in blocchi. L'esempio seguente invierà il corpo in blocchi di 1KB.

httpConnection.setChunkedStreamingMode(1024);

User-Agent

Può accadere che una richiesta restituisca una risposta inaspettata, mentre funziona bene con un vero browser web. Il lato server sta probabilmente bloccando le richieste in base al User-Agent intestazione richiesta. Il URLConnection per impostazione predefinita lo imposterà su Java/1.6.0_19 dove l'ultima parte è ovviamente la versione JRE. È possibile ignorare questo come segue:

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.

Utilizzare la stringa User-Agent da un browser recente.


Gestione degli errori

Se il codice di risposta HTTP è 4nn (Errore del client) o 5nn (errore del server), è possibile vuoi leggere HttpURLConnection#getErrorStream() per vedere se il server ha inviato informazioni di errore utili.

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

Se il codice di risposta HTTP è -1, qualcosa è andato storto con la gestione della connessione e della risposta. L'implementazione HttpURLConnection è in JRE più vecchi un po ' bacata con il mantenimento delle connessioni in vita. È possibile disattivarlo impostando la proprietà di sistema http.keepAlive su false. Puoi farlo a livello di codice all'inizio della tua applicazione:

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

Caricamento file

Useresti normalmente multipart/form-data codifica per contenuti POST misti (dati binari e caratteri). La codifica è descritta in modo più dettagliato in 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();
}

Se l'altro lato è un HttpServlet, poi la sua doPost() il metodo sarà chiamato e le parti saranno disponibili da HttpServletRequest#getPart() (nota, quindi non getParameter() e così via!). Il metodo getPart() è tuttavia relativamente nuovo, è introdotto in Servlet 3.0 (Glassfish 3, Tomcat 7, ecc). Prima di Servlet 3.0, la scelta migliore è utilizzare Apache Commons FileUpload per analizzare una richiesta multipart/form-data. Vedi anche questa risposta per esempi di entrambi gli approcci FileUpload e Servelt 3.0.


Gestione di siti HTTPS non attendibili o configurati in modo errato

A volte è necessario collegare un URL HTTPS, forse perché si sta scrivendo un raschietto web. In tal caso, potresti probabilmente affrontare un {[89] } su alcuni siti HTTPS che non mantiene i loro certificati SSL aggiornati o java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] found o javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name su alcuni siti HTTPS configurati in modo errato.

Il seguente inizializzatore di una volta static nella classe web scraper dovrebbe rendere HttpsURLConnection più indulgente nei confronti di quei siti HTTPS e quindi non gettare più quelle eccezioni.

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

Ultime parole

Il Apache HttpComponents HttpClient è molto più conveniente in tutto questo:)


Analisi ed estrazione di HTML

Se tutto quello che vuoi è analizzare ed estrarre dati da HTML, allora meglio usare un parser HTML come Jsoup

 2552
Author: BalusC, 2018-07-26 12:14:04

Quando si lavora con HTTP è quasi sempre più utile fare riferimento a HttpURLConnection piuttosto che alla classe base URLConnection (poiché URLConnection è una classe astratta quando si chiede URLConnection.openConnection() su un URL HTTP che è ciò che si otterrà comunque).

Quindi puoi invece di affidarti a URLConnection#setDoOutput(true) per impostare implicitamente il metodo di richiesta su POST invece di fare httpURLConnection.setRequestMethod("POST") che alcuni potrebbero trovare più naturale (e che consente anche di specificare altri metodi di richiesta come PUT, SOPPRIMERE , ...).

Fornisce anche costanti HTTP utili in modo da poter fare:

int responseCode = httpURLConnection.getResponseCode();

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

Ispirato da questa e da altre domande su SO, ho creato un open source minimo basic-http-client che incarna la maggior parte delle tecniche trovate qui.

Google-http-java-client è anche una grande risorsa open source.

 49
Author: David Chandler, 2012-06-13 16:37:47

Ci sono 2 opzioni che puoi andare con gli accessi URL HTTP: GET / POST

OTTIENI richiesta:-

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

Richiesta 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
Author: Utkash Bhatt, 2017-05-05 16:40:31

Ti suggerisco di dare un'occhiata al codice su kevinsawicki/http-request, è fondamentalmente un wrapper sopra HttpUrlConnection fornisce un'API molto più semplice nel caso in cui tu voglia solo fare le richieste in questo momento o puoi dare un'occhiata alle fonti (non è troppo grande) per dare un'occhiata a come vengono gestite le connessioni.

Esempio: Fare una richiesta GET con il tipo di contenuto application/json e alcuni parametri di query:

// 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, 2014-11-24 13:43:51

Sono stato anche molto ispirato da questa risposta.

Sono spesso su progetti in cui ho bisogno di fare un po ' di HTTP, e potrei non voler portare molte dipendenze di 3rd party (che portano altri e così via e così via, ecc.)

Ho iniziato a scrivere le mie utility in base ad alcune di questa conversazione (non nessuna dove fatto):

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 {

Quindi ci sono solo un gruppo o metodi statici.

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

Quindi pubblica...

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

Bene si ottiene l'idea....

Ecco i prove:

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


}

Puoi trovare il resto qui:

Https://github.com/RichardHightower/boon

Il mio obiettivo è quello di fornire le cose comuni che si vorrebbe fare in un modo un po ' più semplice allora....

 19
Author: RickHigh, 2013-10-17 05:35:17

Aggiornare

Il nuovo client HTTP fornito con Java 9 ma come parte di un Modulo incubatore denominato jdk.incubator.httpclient. I moduli incubatori sono un mezzo per mettere le API non finali nelle mani degli sviluppatori mentre il Le API progrediscono verso la finalizzazione o la rimozione in un futuro rilasciare.

In Java 9, è possibile inviare una richiesta GET come:

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

Quindi puoi esaminare il HttpResponse restituito:

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

Poiché questo nuovo client HTTP è in java.httpclient modulo jdk.incubator.httpclient, dovresti dichiarare questa dipendenza nel tuo file module-info.java:

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

Inizialmente sono stato ingannato da questo articolo che favorisce HttpClient.

Più tardi mi sono reso conto che {[1] } rimarrà da questo articolo

Come per il blog di Google:

Il client HTTP Apache ha meno bug su Eclair e Froyo. È la scelta migliore per queste versioni. Per il pan di zenzero , HttpURLConnection è la scelta migliore. La sua API semplice e di piccole dimensioni lo rende ideale per Android.

Compressione trasparente e caching di risposta ridurre l'uso della rete, migliorare la velocità e risparmiare la batteria. Le nuove applicazioni dovrebbero utilizzare HttpURLConnection; è dove spenderemo le nostre energie andando avanti.

Dopo aver letto questo articolo e alcune altre domande di stack over flow, sono convinto che HttpURLConnection rimarrà per durate più lunghe.

Alcune delle domande della SE che favoriscono HttpURLConnections:

Su Android, effettuare una richiesta POST con i dati del modulo codificati URL senza utilizzare UrlEncodedFormEntity

HttpPost funziona nel progetto Java, non in Android

 14
Author: Ravindra babu, 2017-05-23 11:55:13

Puoi anche usare JdkRequest da jcabi-http (sono uno sviluppatore), che fa tutto questo lavoro per te, decorando HttpURLConnection, attivando richieste HTTP e analizzando le risposte, ad esempio:

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

Controlla questo post del blog per maggiori informazioni: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

 11
Author: yegor256, 2014-04-11 18:54:16

C'è anche OkHttp , che è un client HTTP efficiente per impostazione predefinita:

  • Il supporto HTTP/2 consente a tutte le richieste allo stesso host di condividere un socket.
  • Il pool di connessioni riduce la latenza della richiesta (se HTTP/2 non è disponibile).
  • GZIP trasparente riduce le dimensioni del download.
  • Il caching delle risposte evita completamente la rete per le richieste ripetute.

Creare prima un'istanza di OkHttpClient:

OkHttpClient client = new OkHttpClient();

Quindi, prepara la tua richiesta GET:

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

Infine, usa OkHttpClient per inviare Request preparato:

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

Per maggiori dettagli, è possibile consultare la documentazione di OkHttp

 11
Author: Ali Dehghani, 2016-01-15 12:06:33

Se si utilizza http get rimuovere questa riga

urlConnection.setDoOutput(true);
 10
Author: Nison Cheruvathur, 2017-12-20 07:15:18