Java URLConnection
Apri connessioni agli URL in Java con URLConnection per leggere risorse e inviare richieste.
Un URL nomina una risorsa; una URLConnection è il collegamento attivo che apri per leggerla o scriverla. Non la si costruisce direttamente — si chiama url.openConnection(), e Java restituisce un oggetto connessione il cui tipo concreto dipende dal protocollo (http:, https:, file:, jar:, …). URLConnection è la classe base indipendente dal protocollo; il capitolo HttpURLConnection tratta la sua sottoclasse specifica per HTTP.
Questa pagina illustra come aprire una connessione, configurare i timeout, leggere le intestazioni della risposta e il corpo, e dove termina l'API protocol-neutral e inizia il lavoro specifico per HTTP.
Apertura e configurazione
URL url = URI.create("http://example.com/data").toURL();
URLConnection conn = url.openConnection(); // not connected yet
conn.setConnectTimeout(2000); // ms to establish the connection
conn.setReadTimeout(2000); // ms to wait for data
conn.connect(); // optional; reading connects implicitlyopenConnection() non tocca la rete — crea semplicemente un oggetto configurabile. La connessione effettiva avviene in modo lazy quando si chiama connect() o, più comunemente, quando si legge per la prima volta da getInputStream(). Imposta i timeout prima di connetterti; entrambi hanno valore predefinito 0, che significa "attendi all'infinito", il che è raramente desiderato.
Lettura della risposta
Tornano due tipi di informazioni: le intestazioni (metadati) e il corpo (uno stream di input).
String type = conn.getContentType(); // e.g. "text/plain; charset=utf-8"
int length = conn.getContentLength(); // -1 if the server did not send it
long when = conn.getLastModified();
try (InputStream in = conn.getInputStream()) {
// read the body bytes
}I getter delle intestazioni come getContentType() sono comodità rispetto al generico getHeaderField("Name"). Leggi sempre il corpo tramite try-with-resources in modo che il socket sottostante venga rilasciato.
Invio di dati
Per inviare un corpo della richiesta, attiva la connessione in modalità output con setDoOutput(true), poi scrivi su getOutputStream(). Per HTTP questo implica un POST. Poiché controllare il metodo, il codice di stato e il flusso degli errori richiede comportamenti specifici di HTTP, tale lavoro appartiene a HttpURLConnection.
Un esempio pratico: lettura di una risorsa tramite connessione
Questo programma fornisce un piccolo corpo di testo da un HttpServer di loopback, apre una URLConnection generica verso di esso, ispeziona le intestazioni della risposta e trasmette il corpo riga per riga — completamente offline.
Cosa trarre dall'esecuzione:
url.openConnection()ha restituito unaURLConnectionsenza connettersi; il round trip di rete è avvenuto solo quando è stato chiamatogetInputStream(). Questa natura lazy è la ragione per cui i timeout e le proprietà delle richieste devono essere impostati prima — una volta letto il corpo, la connessione è già stabilita e queste impostazioni sono bloccate.- I getter delle intestazioni e lo stream del corpo sono due canali separati.
getContentType()egetContentLength()leggono i metadati della risposta, mentregetInputStream()legge il payload. Il server ha impostatoContent-Typeesplicitamente, e la connessione lo ha esposto sia tramite il getter tipizzato sia tramite il genericogetHeaderField("Content-Type"). getContentLength()ha restituito il conteggio reale dei byte perché il server ha inviato un'intestazioneContent-Length. Quando un server la omette (risposte chunked), restituisce-1— quindi il codice che pre-dimensiona un buffer da esso deve gestire il caso-1.- Il corpo è stato letto tramite try-with-resources, garantendo che il socket venga liberato anche in caso di eccezione. Far trapelare stream di connessione esaurisce il pool di connessioni e alla fine il limite dei descrittori di file del sistema operativo — la chiusura non è opzionale nel codice di networking.
URLConnectionè deliberatamente protocol-neutral: nulla qui ha menzionato codici di stato HTTP o metodi di richiesta. Leggere lo stato, scegliere GET vs POST e accedere al flusso degli errori richiede il cast aHttpURLConnection, come illustrato nel prossimo capitolo.