W3docs

Java HttpURLConnection

Esegui richieste HTTP in Java con l'API legacy HttpURLConnection del JDK.

HttpURLConnection è la sottoclasse HTTP-aware di URLConnection. Quando chiami openConnection() su un URL http: o https:, l'oggetto restituito è un HttpURLConnection — esegui il cast per accedere alle funzionalità HTTP specifiche: impostare il metodo della richiesta, leggere il codice di stato e ottenere lo stream degli errori separato. È il client HTTP originale del JDK, disponibile sin da Java 1.1.

Questo capitolo tratta il cast della connessione e la scelta del metodo, l'invio di un corpo della richiesta, il codice di stato e i due stream di risposta (la classica trappola dello stream degli errori), e un esempio completo di round trip POST che puoi eseguire.

Nota moderna: per il nuovo codice, preferisci java.net.http.HttpClient — è più pulito, supporta HTTP/2 e gestisce l'async. HttpURLConnection è ancora molto diffuso nelle codebase più vecchie, quindi vale la pena conoscerlo bene.

Cast e scelta del metodo

URL url = URI.create("http://example.com/api").toURL();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");                       // GET is the default
conn.setRequestProperty("Content-Type", "application/json");
conn.setConnectTimeout(2000);
conn.setReadTimeout(2000);

setRequestMethod accetta "GET", "POST", "PUT", "DELETE", ecc. Aggiungi header di richiesta con setRequestProperty.

Invio del corpo della richiesta

Per inviare un corpo devi abilitarlo con setDoOutput(true) (che imposta anche il metodo predefinito su POST), poi scrivere sullo stream di output:

conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
    os.write(payload.getBytes(StandardCharsets.UTF_8));
}

Codice di stato e i due stream

La funzionalità HTTP distintiva è il codice di stato, e la trappola che ne consegue:

int code = conn.getResponseCode();          // triggers the request
InputStream body = (code >= 200 && code < 400)
        ? conn.getInputStream()             // success body
        : conn.getErrorStream();            // error body (4xx/5xx)

getInputStream() lancia IOException in caso di risposta 4xx/5xx. Il corpo dell'errore si trova su uno stream diverso, getErrorStream(). Dimenticarsi di questo è il classico bug di HttpURLConnection: una risposta di errore fa esplodere il programma invece di permetterti di leggere la spiegazione del server. Ramifica sempre su getResponseCode() per primo. Concludi con conn.disconnect().

Un esempio completo: un round trip POST

Questo programma avvia un server loopback che restituisce in eco il corpo della richiesta con un 201 Created, poi esegue un POST tramite HttpURLConnection: impostando il metodo, scrivendo un corpo, leggendo lo stato e scegliendo il giusto stream.

java— editable, runs on the server

Cosa ricavare dall'esecuzione:

  • Il cast di URLConnection a HttpURLConnection ha sbloccato il livello HTTP: setRequestMethod("POST"), getResponseCode() e getResponseMessage() esistono solo sulla sottoclasse. Per un URL http: l'oggetto è davvero un HttpURLConnection, quindi il cast riesce sempre.
  • L'invio di un corpo ha richiesto setDoOutput(true) prima di scrivere su getOutputStream(). Senza quella chiamata la connessione rimane in sola lettura e la scrittura fallisce — abilitare l'output è l'interruttore che trasforma un GET in una richiesta con corpo.
  • getResponseCode() ha restituito 201 ed è ciò che ha effettivamente inviato la richiesta al server. Il codice di stato è la prima cosa da leggere, perché la decisione successiva — quale stream leggere — dipende da esso.
  • L'esempio ha scelto tra getInputStream() e getErrorStream(). Qui 201 è un successo quindi lo stream di input ha trasportato il corpo in eco, ma con una risposta 4xx/5xx getInputStream() avrebbe lanciato un'eccezione e il messaggio del server sarebbe stato raggiungibile solo tramite getErrorStream(). Questa biforcazione è il punto più critico dell'API.
  • Il flusso ha richiesto cinque o più chiamate di configurazione per un solo POST, e disconnect() per la pulizia. Quella verbosità — stream manuali, la trappola dello stream degli errori, nessun async integrato — è esattamente il motivo per cui esiste HttpClient.

Quando usare HttpURLConnection

Ricorri a HttpURLConnection quando sei su un JDK più vecchio (precedente a Java 11), quando una libreria o codebase già lo standardizza, oppure quando vuoi evitare di aggiungere dipendenze extra per una singola chiamata semplice. Per qualsiasi cosa nuova e non banale — riutilizzo delle connessioni, HTTP/2, async o oggetti richiesta/risposta più puliti — preferisci il moderno HttpClient. Se hai solo bisogno di leggere da un URL senza controllo HTTP specifico, le classi plain URL e URLConnection sono sufficienti.

Practice

Pratica
Un client esegue un PUT con 'HttpURLConnection'. Quando il server restituisce '400 Bad Request', il codice va in crash con una 'IOException' su 'conn.getInputStream()' invece di registrare il messaggio di errore del server. Qual è la correzione corretta?
Un client esegue un PUT con 'HttpURLConnection'. Quando il server restituisce '400 Bad Request', il codice va in crash con una 'IOException' su 'conn.getInputStream()' invece di registrare il messaggio di errore del server. Qual è la correzione corretta?
Was this page helpful?