W3docs

Classe URL in Java

Analizza e rappresenta URL in Java con la classe URL: protocollo, host, porta, percorso, query.

Un URL (Uniform Resource Locator) identifica una risorsa e il modo per raggiungerla: https://www.example.com:443/docs?q=net#top. Java lo modella con java.net.URL, che analizza un URL nei suoi componenti e può aprire una connessione per recuperarlo. Questo capitolo riguarda l'analisi e la struttura; l'apertura di una connessione per recuperare dati è trattata in Java URLConnection.

Questa pagina illustra le parti di un URL, i getter che le espongono, come costruire un URL (inclusa la risoluzione di riferimenti relativi) e perché il codice moderno dovrebbe preferire URI rispetto ai costruttori stringa deprecati di URL.

L'anatomia di un URL

  https://user:[email protected]:8443/docs/java?topic=net#intro
  └─┬─┘   └──┬──┘ └──────┬───────┘└┬─┘└───┬────┘ └────┬────┘└─┬─┘
 protocol  userInfo     host     port   path        query    ref

java.net.URL espone ogni parte tramite un getter: getProtocol(), getUserInfo(), getHost(), getPort(), getPath(), getQuery() e getRef() (il frammento). getPort() restituisce -1 quando non è specificata nessuna porta; getDefaultPort() fornisce quella predefinita del protocollo (80 per http, 443 per https).

Costruire un URL

URL url = new URL("https://example.com/path?x=1");      // from a string
URL rel = new URL(base, "../images/logo.png");          // relative to a base

Il costruttore a due argomenti risolve un riferimento relativo rispetto a un URL base — la stessa regola usata da un browser per un link in una pagina. È il modo per trasformare ../images/logo.png su una pagina a /a/b/page.html nell'URL assoluto /a/images/logo.png.

Preferire URI per l'analisi e la validazione

Nei JDK moderni i costruttori stringa di URL sono deprecati. URL è ora pensato per aprire connessioni, non per analizzare o validare. Per la sola analisi, usa java.net.URI e converti solo quando hai effettivamente bisogno di connetterti:

URI uri = URI.create("https://example.com/path?x=1");   // parse / validate
URL url = uri.toURL();                                   // only to open a connection

C'è anche una trappola notoria da conoscere: URL.equals() e URL.hashCode() possono eseguire una risoluzione DNS per confrontare gli host, rendendoli lenti e dipendenti dalla rete. Non inserire mai oggetti URL in un HashSet né usarli come chiavi di mappa — usa URI, la cui uguaglianza è puramente testuale.

Un esempio pratico: scomporre e risolvere URL

Questo programma analizza un URL completo nei suoi componenti, risolve un riferimento relativo e mette a confronto URL con URI — tutto offline, poiché l'analisi non tocca la rete.

java— editable, runs on the server

Cosa ricavare dall'esecuzione:

  • Ogni getter ha estratto una porzione etichettata dalla singola stringa URL: protocollo, informazioni utente, host, porta, percorso, query e il frammento #intro tramite getRef(). Un URL è un valore strutturato, non solo testo — analizzarlo una volta e leggerne i campi è preferibile rispetto a usare String.split su / e ?.
  • L'URL senza porta ha restituito getPort() == -1 mentre getDefaultPort() ha restituito 80. La distinzione è importante quando si apre una connessione: -1 significa "la porta è stata omessa" e si fa ricorso al valore predefinito del protocollo, senza trattare -1 come una porta reale.
  • base.resolve("../images/logo.png") ha prodotto un URL assoluto risalendo da /a/b/ — la stessa risoluzione dei link relativi eseguita da un browser. I riferimenti relativi vengono risolti rispetto a una base, quindi il percorso della base determina dove atterra ...
  • L'esempio ha costruito l'URL tramite URI.create(...).toURL() anziché il deprecato new URL(String). Nei JDK moderni questo è il percorso raccomandato: analizza e valida con URI, converti in URL solo nel momento in cui apri una connessione.
  • URI.equals ha confrontato due URI identici in modo testuale restituendo true senza alcun accesso alla rete. Questo è il modo sicuro per confrontare e per usare come chiavi di mappa — URL.equals avrebbe potuto innescare una risoluzione DNS per risolvere l'host, che è lenta e può fallire offline.

Una volta ottenuto un URL, il passo successivo è solitamente aprirlo. Per uno stream a basso livello, chiama url.openConnection() (vedi Java URLConnection); per un'API HTTP moderna ad alto livello, preferisci Java HttpClient.

Esercitazione

Pratica
Un collega memorizza le risorse scaricate in un 'HashSet<URL>' per evitare duplicati, e nota che il programma è lento e a volte si blocca quando è offline. Qual è la spiegazione corretta e la soluzione?
Un collega memorizza le risorse scaricate in un 'HashSet<URL>' per evitare duplicati, e nota che il programma è lento e a volte si blocca quando è offline. Qual è la spiegazione corretta e la soluzione?
Was this page helpful?