URL Class in Java
A URL (Uniform Resource Locator) is the address of a resource on a network, such as https://www.poolstring.com/java/strings. Java's java.net.URL class represents one, lets you read its parts, and can open a connection to the resource. Its close relative java.net.URI represents the more general idea of an identifier and is the class modern code uses for parsing and building addresses. Since Java 20, the URL constructors are deprecated, and the recommended way to get a URL is URI.create(text).toURL(). In this lesson, you will learn the parts of a URL, the methods that read them, how relative addresses are resolved, and how to encode text safely.
The Parts of a URL
| Part | Example | Notes |
|---|---|---|
| Protocol (scheme) | https | How to talk to the server |
| Host | www.poolstring.com | Which machine |
| Port | 8443 | Optional; each protocol has a default (80 for http, 443 for https) |
| Path | /java/search | Which resource on that machine |
| Query | q=hash+map&page=2 | Extra parameters, after ? |
| Fragment (reference) | results | A place inside the page, after #; never sent to the server |
Methods of URL
| Method | Description |
|---|---|
getProtocol() | It is used to get the protocol, such as https. |
getHost() | It returns the host name. |
getPort() | It returns the port, or -1 if the address doesn't state one. |
getDefaultPort() | It returns the protocol's default port. |
getPath() | It returns the path. |
getQuery() | It returns the query, or null if there is none. |
getFile() | It returns the path plus the query. |
getRef() | It returns the fragment, or null. |
getAuthority() | It returns the host and port together. |
toURI() | It converts the URL to a URI. |
openConnection(), openStream() | They connect to the resource (see "URLConnection Class in Java"). |
Example: Reading the Parts
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class Parts {
public static void main(String[] args) throws Exception {
URL url = URI.create("https://www.poolstring.com:8443"
+ "/java/search?q=hash+map&page=2#results").toURL();
System.out.println("protocol: " + url.getProtocol());
System.out.println("host: " + url.getHost());
System.out.println("port: " + url.getPort());
System.out.println("default: " + url.getDefaultPort());
System.out.println("path: " + url.getPath());
System.out.println("query: " + url.getQuery());
System.out.println("file: " + url.getFile());
System.out.println("ref: " + url.getRef());
System.out.println("authority: " + url.getAuthority());
URL plain = URI.create("https://www.poolstring.com/java").toURL();
System.out.println(plain.getPort() + " "
+ plain.getDefaultPort() + " " + plain.getQuery());
URI base =
URI.create("https://www.poolstring.com/java/collections/");
System.out.println(base.resolve("hashmap-internals"));
System.out.println(base.resolve("../strings"));
System.out.println(base.resolve("/about"));
System.out.println(
URI.create("https://www.poolstring.com/a/./b/../c").normalize());
String q = URLEncoder.encode(
"Navika & Srihitha: 100%", StandardCharsets.UTF_8);
System.out.println(q);
System.out.println(URLDecoder.decode(q, StandardCharsets.UTF_8));
try {
URI.create("ftp2://x").toURL();
} catch (MalformedURLException e) {
System.out.println("MalformedURLException: " + e.getMessage());
}
try {
new URI("https://www.poolstring.com/a b");
} catch (URISyntaxException e) {
System.out.println("URISyntaxException: " + e.getReason());
}
try {
URI.create("/java/strings").toURL();
} catch (IllegalArgumentException e) {
System.out.println("IllegalArgumentException: " + e.getMessage());
}
}
}protocol: https
host: www.poolstring.com
port: 8443
default: 443
path: /java/search
query: q=hash+map&page=2
file: /java/search?q=hash+map&page=2
ref: results
authority: www.poolstring.com:8443
-1 443 null
https://www.poolstring.com/java/collections/hashmap-internals
https://www.poolstring.com/java/strings
https://www.poolstring.com/about
https://www.poolstring.com/a/c
Navika+%26+Srihitha%3A+100%25
Navika & Srihitha: 100%
MalformedURLException: unknown protocol: ftp2
URISyntaxException: Illegal character in path
IllegalArgumentException: URI is not absoluteExplanation:
URI.create(...).toURL()is the modern way to make aURL. The first nine lines print each part of the address.-1 443 null: an address without a port givesgetPort() == -1, not 443. UsegetDefaultPort()for the port that will really be used. A missing query isnull.resolveworks out a relative address against a base, exactly as a browser does for links: a plain name is added to the base's folder,../goes up one level, and a leading/starts again from the host.normalize()removes.and..steps from a path.URLEncoder.encodemakes text safe to put in a query: the space becomes+, and&,:and%become%26,%3Aand%25.URLDecoder.decodereverses it. Always pass the character set,StandardCharsets.UTF_8.- The three errors: a protocol Java doesn't know gives
MalformedURLException; an illegal character (the space) givesURISyntaxException; and a relative address can't become aURL, because aURLmust say where the resource is.
URL vs URI
| Point | URI | URL |
|---|---|---|
| Represents | Any identifier, absolute or relative | A locator: it must have a protocol Java can handle |
| Validation | Strict syntax checking | Very little |
equals and hashCode | Compare the text; fast and safe | May do a DNS lookup to compare hosts; slow and surprising |
| Relative addresses | Supported (resolve, relativize) | Not supported |
| Opens connections | No | Yes |
| Status | The recommended class | Constructors deprecated since Java 20 |
Compiling new URL("https://www.poolstring.com") on a current JDK gives:
Dep.java:2: warning: [deprecation] URL(String) in URL has been deprecatedThe constructors were deprecated because they don't validate or encode the address properly, which has caused parsing bugs and security problems.
Common Mistakes
Treating getPort() as the real port. It is -1 when the address has no explicit port.
Building queries by joining strings without encoding. A value containing &, =, a space or a non-English letter breaks the address. Encode each value with URLEncoder.
Encoding the whole URL. URLEncoder is for a single query value; applied to a whole address it also encodes : and /.
Using new URL(...). It still works, but it is deprecated; use URI.create(...).toURL().
Interview Corner
What is the difference between a URL and a URI in Java?
A URI is a general identifier for a resource and may be absolute or relative; the class performs strict syntax checking and supports resolving and normalizing, but can't open connections. A URL is a URI that also says how to locate the resource, so it must be absolute with a supported protocol, and it can open a connection. URL.equals may perform DNS resolution, so URI is preferred for storing and comparing addresses. Since Java 20 the URL constructors are deprecated in favor of URI.create(...).toURL().
What are the components of a URL?
Protocol (scheme), host, optional port, path, optional query string after ?, and optional fragment after #. The host and port together form the authority. In Java they are read with getProtocol(), getHost(), getPort(), getPath(), getQuery() and getRef().
Practice
- Easy: Print the host, path and query of
https://www.poolstring.com/search?q=streams. - Harder: Write a method that takes a base address and a
Map<String, String>of parameters and returns aURIwith a correctly encoded query string.
Key Takeaways
Was this tutorial helpful?