URL Class in Java

Naveen AnamaneniUpdated · 7 min read

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

Protocol, host, port, path, query and fragment
PartExampleNotes
Protocol (scheme)httpsHow to talk to the server
Hostwww.poolstring.comWhich machine
Port8443Optional; each protocol has a default (80 for http, 443 for https)
Path/java/searchWhich resource on that machine
Queryq=hash+map&page=2Extra parameters, after ?
Fragment (reference)resultsA place inside the page, after #; never sent to the server

Methods of URL

MethodDescription
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

Parts.java▶ Try it
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());
        }
    }
}
Output
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 absolute

Explanation:

  • URI.create(...).toURL() is the modern way to make a URL. The first nine lines print each part of the address.
  • -1 443 null: an address without a port gives getPort() == -1, not 443. Use getDefaultPort() for the port that will really be used. A missing query is null.
  • resolve works 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.encode makes text safe to put in a query: the space becomes +, and &, : and % become %26, %3A and %25. URLDecoder.decode reverses 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) gives URISyntaxException; and a relative address can't become a URL, because a URL must say where the resource is.

URL vs URI

PointURIURL
RepresentsAny identifier, absolute or relativeA locator: it must have a protocol Java can handle
ValidationStrict syntax checkingVery little
equals and hashCodeCompare the text; fast and safeMay do a DNS lookup to compare hosts; slow and surprising
Relative addressesSupported (resolve, relativize)Not supported
Opens connectionsNoYes
StatusThe recommended classConstructors deprecated since Java 20

Compiling new URL("https://www.poolstring.com") on a current JDK gives:

Compiler output (javac -Xlint:deprecation)
Dep.java:2: warning: [deprecation] URL(String) in URL has been deprecated

The 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

  1. Easy: Print the host, path and query of https://www.poolstring.com/search?q=streams.
  2. Harder: Write a method that takes a base address and a Map<String, String> of parameters and returns a URI with a correctly encoded query string.

Quick check: URL class

4 questions
1What does getPort() return for https://www.poolstring.com/java?
2What is the recommended way to create a URL today?
3Which part of a URL is never sent to the server?
4Why avoid URL objects as HashMap keys?

Key Takeaways

Was this tutorial helpful?

Lesson 478 of 482