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 refjava.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 baseEl 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 connectionTambié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.
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
#intromediantegetRef(). Una URL es un valor estructurado, no solo texto — analizarla una vez y leer los campos es mejor que construir manualmente unString.spliten/y?. - La URL sin puerto informó
getPort() == -1mientras quegetDefaultPort()devolvió80. La distinción importa cuando construyes una conexión:-1significa "el puerto fue omitido," y debes recurrir al valor predeterminado del protocolo en lugar de tratar-1como 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
URLmedianteURI.create(...).toURL()en lugar delnew URL(String)en desuso. En los JDK modernos ese es el camino recomendado: analizar y validar conURI, convertir aURLsolo en el momento en que abras una conexión. URI.equalscomparó dos URIs idénticas textualmente y devolviótruesin involucrar la red. Esta es la forma segura de comparar y usar como claves de mapa —URL.equalspodrí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.