Classe URL do Java
Analise e represente URLs em Java com a classe URL — protocolo, host, porta, caminho, query.
Uma URL (Uniform Resource Locator) identifica um recurso e como acessá-lo: https://www.example.com:443/docs?q=net#top. O Java a modela com java.net.URL, que tanto analisa uma URL em seus componentes quanto pode abrir uma conexão para buscá-la. Este capítulo trata de análise e estrutura; abrir uma conexão para de fato buscar bytes é abordado em Java URLConnection.
Esta página cobre as partes de uma URL, os getters que as expõem, como construir uma URL (incluindo a resolução de referências relativas) e por que o código moderno deve preferir URI em vez dos construtores de string URL deprecados.
A anatomia de uma URL
https://user:[email protected]:8443/docs/java?topic=net#intro
└─┬─┘ └──┬──┘ └──────┬───────┘└┬─┘└───┬────┘ └────┬────┘└─┬─┘
protocol userInfo host port path query refjava.net.URL expõe cada parte por meio de um getter: getProtocol(), getUserInfo(), getHost(), getPort(), getPath(), getQuery() e getRef() (o fragmento). getPort() retorna -1 quando nenhuma porta está escrita; getDefaultPort() fornece o padrão do protocolo (80 para http, 443 para https).
Construindo uma 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 baseO construtor de dois argumentos resolve uma referência relativa em relação a uma URL base — a mesma regra que um navegador usa para um link em uma página. É assim que você converte ../images/logo.png em uma página em /a/b/page.html para o absoluto /a/images/logo.png.
Prefira URI para análise e validação
Nos JDKs modernos, os construtores de string URL estão deprecados. URL agora se destina a abrir conexões, não para análise ou validação. Para análise pura, use java.net.URI e converta quando precisar efetivamente conectar:
URI uri = URI.create("https://example.com/path?x=1"); // parse / validate
URL url = uri.toURL(); // only to open a connectionHá também uma armadilha notória a conhecer: URL.equals() e URL.hashCode() podem realizar resolução DNS para comparar hosts, tornando-os lentos e dependentes de rede. Nunca coloque objetos URL em um HashSet ou use-os como chaves de mapa — use URI, cuja igualdade é puramente textual.
Um exemplo prático: dissecando e resolvendo URLs
Este programa analisa uma URL totalmente carregada em suas partes, resolve uma referência relativa e contrasta URL com o URI voltado para análise — tudo offline, pois a análise não toca a rede.
O que extrair da execução:
- Cada getter extraiu uma fatia rotulada da string URL única: protocolo, informações do usuário, host, porta, caminho, query e o fragmento
#introviagetRef(). Uma URL é um valor estruturado, não apenas texto — analisá-la uma vez e ler campos é melhor do que implementar manualmenteString.splitem/e?. - A URL sem porta reportou
getPort() == -1enquantogetDefaultPort()retornou80. A distinção importa quando você constrói uma conexão:-1significa "a porta foi omitida", e você recorre ao padrão do protocolo em vez de tratar-1como uma porta real. base.resolve("../images/logo.png")produziu uma URL absoluta subindo de/a/b/— exatamente a resolução de link relativo que um navegador realiza. Referências relativas são resolvidas em relação a uma base, portanto o caminho da base determina onde..chega.- O exemplo construiu a
URLviaURI.create(...).toURL()em vez donew URL(String)deprecado. Nos JDKs modernos, esse é o caminho recomendado: analise e valide comURI, converta paraURLapenas no momento em que abrir uma conexão. URI.equalscomparou dois URIs idênticos textualmente e retornoutruesem envolver a rede. Essa é a maneira segura de comparar e usar como chaves de mapa —URL.equalspoderia ter acionado uma consulta DNS para resolver o host, o que é lento e pode falhar offline.
Assim que você tem uma URL, o próximo passo geralmente é abri-la. Para um stream de baixo nível, chame url.openConnection() (veja Java URLConnection); para uma API HTTP moderna e de alto nível, prefira o Java HttpClient.