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.
Cosa ricavare dall'esecuzione:
- Il cast di
URLConnectionaHttpURLConnectionha sbloccato il livello HTTP:setRequestMethod("POST"),getResponseCode()egetResponseMessage()esistono solo sulla sottoclasse. Per un URLhttp:l'oggetto è davvero unHttpURLConnection, quindi il cast riesce sempre. - L'invio di un corpo ha richiesto
setDoOutput(true)prima di scrivere sugetOutputStream(). 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 restituito201ed è 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()egetErrorStream(). Qui201è un successo quindi lo stream di input ha trasportato il corpo in eco, ma con una risposta 4xx/5xxgetInputStream()avrebbe lanciato un'eccezione e il messaggio del server sarebbe stato raggiungibile solo tramitegetErrorStream(). 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 esisteHttpClient.
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.