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 refjava.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 baseIl 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 connectionC'è 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.
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
#introtramitegetRef(). Un URL è un valore strutturato, non solo testo — analizzarlo una volta e leggerne i campi è preferibile rispetto a usareString.splitsu/e?. - L'URL senza porta ha restituito
getPort() == -1mentregetDefaultPort()ha restituito80. La distinzione è importante quando si apre una connessione:-1significa "la porta è stata omessa" e si fa ricorso al valore predefinito del protocollo, senza trattare-1come 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'
URLtramiteURI.create(...).toURL()anziché il deprecatonew URL(String). Nei JDK moderni questo è il percorso raccomandato: analizza e valida conURI, converti inURLsolo nel momento in cui apri una connessione. URI.equalsha confrontato due URI identici in modo testuale restituendotruesenza alcun accesso alla rete. Questo è il modo sicuro per confrontare e per usare come chiavi di mappa —URL.equalsavrebbe 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.