W3docs

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    ref

java.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 base

O 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 connection

Há 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.

java— editable, runs on the server

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 #intro via getRef(). Uma URL é um valor estruturado, não apenas texto — analisá-la uma vez e ler campos é melhor do que implementar manualmente String.split em / e ?.
  • A URL sem porta reportou getPort() == -1 enquanto getDefaultPort() retornou 80. A distinção importa quando você constrói uma conexão: -1 significa "a porta foi omitida", e você recorre ao padrão do protocolo em vez de tratar -1 como 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 URL via URI.create(...).toURL() em vez do new URL(String) deprecado. Nos JDKs modernos, esse é o caminho recomendado: analise e valide com URI, converta para URL apenas no momento em que abrir uma conexão.
  • URI.equals comparou dois URIs idênticos textualmente e retornou true sem envolver a rede. Essa é a maneira segura de comparar e usar como chaves de mapa — URL.equals poderia 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.

Prática

Prática
Um colega armazena recursos baixados em um 'HashSet<URL>' para evitar duplicatas e percebe que o programa é lento e às vezes trava quando está offline. Qual é a explicação correta e a correção?
Um colega armazena recursos baixados em um 'HashSet<URL>' para evitar duplicatas e percebe que o programa é lento e às vezes trava quando está offline. Qual é a explicação correta e a correção?
Was this page helpful?