W3docs

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 implicitly

openConnection() 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.

java— editable, runs on the server

Cosa trarre dall'esecuzione:

  • url.openConnection() ha restituito una URLConnection senza connettersi; il round trip di rete è avvenuto solo quando è stato chiamato getInputStream(). 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() e getContentLength() leggono i metadati della risposta, mentre getInputStream() legge il payload. Il server ha impostato Content-Type esplicitamente, e la connessione lo ha esposto sia tramite il getter tipizzato sia tramite il generico getHeaderField("Content-Type").
  • getContentLength() ha restituito il conteggio reale dei byte perché il server ha inviato un'intestazione Content-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 a HttpURLConnection, come illustrato nel prossimo capitolo.

Esercitazione

Pratica
Una routine di download chiama 'url.openConnection()' e poi avvia immediatamente un timer di 30 secondi prima di chiamare 'getInputStream()', aspettandosi che la connessione sia già aperta. Non imposta mai alcun timeout. Quale affermazione è corretta?
Una routine di download chiama 'url.openConnection()' e poi avvia immediatamente un timer di 30 secondi prima di chiamare 'getInputStream()', aspettandosi che la connessione sia già aperta. Non imposta mai alcun timeout. Quale affermazione è corretta?
Was this page helpful?