W3docs

Clase URL de Java

Analiza y representa URLs en Java con la clase URL: protocolo, host, puerto, ruta y consulta.

Una URL (Uniform Resource Locator) identifica un recurso y cómo acceder a él: https://www.example.com:443/docs?q=net#top. Java lo modela con java.net.URL, que tanto analiza una URL en sus componentes como puede abrir una conexión para obtenerla. Este capítulo trata sobre el análisis y la estructura; abrir una conexión para obtener bytes reales se cubre en Java URLConnection.

Esta página cubre las partes de una URL, los getters que las exponen, cómo construir una URL (incluyendo la resolución de referencias relativas) y por qué el código moderno debería usar URI en lugar de los constructores de cadena URL que están en desuso.

La anatomía de una URL

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

java.net.URL expone cada parte a través de un getter: getProtocol(), getUserInfo(), getHost(), getPort(), getPath(), getQuery() y getRef() (el fragmento). getPort() devuelve -1 cuando no se especifica puerto; getDefaultPort() proporciona el valor predeterminado del protocolo (80 para http, 443 para https).

Construir una 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

El constructor de dos argumentos resuelve una referencia relativa contra una URL base — la misma regla que usa un navegador para un enlace en una página. Es la forma de convertir ../images/logo.png en una página ubicada en /a/b/page.html en la ruta absoluta /a/images/logo.png.

Preferir URI para análisis y validación

En los JDK modernos, los constructores de cadena URL están en desuso. URL ahora está pensado para abrir conexiones, no para analizar o validar. Para análisis puro, usa java.net.URI y conviértelo solo cuando necesites conectarte:

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

También hay una trampa notable que debes conocer: URL.equals() y URL.hashCode() pueden realizar resolución DNS para comparar hosts, lo que los hace lentos y dependientes de la red. Nunca pongas objetos URL en un HashSet ni los uses como claves de mapa — usa URI, cuya igualdad es puramente textual.

Un ejemplo práctico: diseccionando y resolviendo URLs

Este programa analiza una URL completa en sus partes, resuelve una referencia relativa y contrasta URL con el URI más amigable para el análisis — todo sin conexión, ya que el análisis no toca la red.

java— editable, runs on the server

Lo que hay que extraer de la ejecución:

  • Cada getter extrajo un fragmento etiquetado de la cadena URL única: protocolo, información de usuario, host, puerto, ruta, consulta y el fragmento #intro mediante getRef(). Una URL es un valor estructurado, no solo texto — analizarla una vez y leer los campos es mejor que construir manualmente un String.split en / y ?.
  • La URL sin puerto informó getPort() == -1 mientras que getDefaultPort() devolvió 80. La distinción importa cuando construyes una conexión: -1 significa "el puerto fue omitido," y debes recurrir al valor predeterminado del protocolo en lugar de tratar -1 como un puerto real.
  • base.resolve("../images/logo.png") produjo una URL absoluta al subir desde /a/b/ — exactamente la resolución de enlaces relativos que realiza un navegador. Las referencias relativas se resuelven contra una base, por lo que la ruta de la base determina dónde aterriza ...
  • El ejemplo construyó la URL mediante URI.create(...).toURL() en lugar del new URL(String) en desuso. En los JDK modernos ese es el camino recomendado: analizar y validar con URI, convertir a URL solo en el momento en que abras una conexión.
  • URI.equals comparó dos URIs idénticas textualmente y devolvió true sin involucrar la red. Esta es la forma segura de comparar y usar como claves de mapa — URL.equals podría haber desencadenado una búsqueda DNS para resolver el host, lo cual es lento y puede fallar sin conexión.

Una vez que tienes una URL, el siguiente paso suele ser abrirla. Para un flujo de bajo nivel, llama a url.openConnection() (ver Java URLConnection); para una API HTTP moderna de alto nivel, prefiere el Java HttpClient.

Práctica

Práctica
Un compañero de equipo almacena los recursos descargados en un 'HashSet<URL>' para omitir duplicados y nota que el programa es lento y a veces se cuelga sin conexión. ¿Cuál es la explicación correcta y la solución?
Un compañero de equipo almacena los recursos descargados en un 'HashSet<URL>' para omitir duplicados y nota que el programa es lento y a veces se cuelga sin conexión. ¿Cuál es la explicación correcta y la solución?
Was this page helpful?