URLConnection Class in Java

Naveen AnamaneniUpdated · 5 min read

URLConnection represents a communication link between a Java program and a resource identified by a URL. You get one by calling url.openConnection(), set options on it, and then read the response headers and the body. It is an abstract class: for an http or https address, the object you receive is really an HttpURLConnection. URLConnection has been part of Java since version 1.0. For new HTTP code, "HttpClient in Java" is the better tool, but URLConnection is still common in existing code and remains the way to read non-HTTP addresses such as file: and jar:. In this lesson, you will learn its lifecycle and methods, and read a resource with it.

The Lifecycle

StepWhat you doMethods
1. CreateAsk the URL for a connection object. Nothing is sent yet.url.openConnection()
2. ConfigureSet timeouts and request headers. Must happen before connecting.setConnectTimeout, setReadTimeout, setRequestProperty, setDoOutput
3. ConnectHappens when you call connect(), or automatically on the first read of headers or body.connect()
4. ReadRead the response headers and the body.getContentType, getHeaderField, getInputStream
5. CloseClose the input stream.close() on the stream

Methods

MethodDescription
setConnectTimeout(millis)It is used to limit how long connecting may take.
setReadTimeout(millis)It limits how long a read may wait for data.
setRequestProperty(name, value)It sets a request header, such as User-Agent or Accept.
setDoOutput(true)It says you will send a body (for HTTP, this makes the request a POST).
getInputStream()It returns the stream to read the response body.
getOutputStream()It returns the stream to write the request body.
getContentType()It returns the Content-Type header.
getContentLengthLong()It returns the body's length, or -1 if unknown.
getHeaderField(name)It returns one response header.
getHeaderFields()It returns all response headers as a map.
getLastModified(), getDate()They return those headers as times in milliseconds.

Example: Reading a Text Resource

To run without an internet connection, this example first starts a tiny web server inside the program (the JDK includes one, com.sun.net.httpserver.HttpServer), then reads from it:

Conn.java▶ Try it
import com.sun.net.httpserver.HttpServer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
 
public class Conn {
    public static void main(String[] args) throws Exception {
        HttpServer server =
            HttpServer.create(new InetSocketAddress("localhost", 0), 0);
        server.createContext("/marks.txt", exchange -> {
            byte[] body = "Navika,91\nSrihitha,84\nAdvitha,78\n"
                .getBytes(StandardCharsets.UTF_8);
            exchange.getResponseHeaders()
                .set("Content-Type", "text/plain; charset=utf-8");
            exchange.sendResponseHeaders(200, body.length);
            exchange.getResponseBody().write(body);
            exchange.close();
        });
        server.start();
        int port = server.getAddress().getPort();
        try {
            URLConnection conn = URI
                .create("http://localhost:" + port + "/marks.txt")
                .toURL().openConnection();
            conn.setConnectTimeout(3000);
            conn.setReadTimeout(3000);
            conn.setRequestProperty("User-Agent", "PoolString-Lesson");
 
            System.out.println("type:   " + conn.getContentType());
            System.out.println("length: " + conn.getContentLengthLong());
            System.out.println("HTTP?   "
                + (conn instanceof HttpURLConnection));
            try (BufferedReader in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(),
                        StandardCharsets.UTF_8))) {
                String line;
                while ((line = in.readLine()) != null) {
                    System.out.println("  " + line);
                }
            }
        } finally {
            server.stop(0);
        }
    }
}
Output
type:   text/plain; charset=utf-8
length: 33
HTTP?   true
  Navika,91
  Srihitha,84
  Advitha,78

Explanation:

  1. The first half sets up the local server: it answers /marks.txt with three lines of text. In real use, this part doesn't exist; you read from someone else's server.
  2. openConnection() only creates the object. The timeouts and the User-Agent header are set before anything is sent.
  3. getContentType() is the first call that needs the response, so the connection is made here, implicitly. The request goes out and the headers come back.
  4. conn instanceof HttpURLConnection is true: for HTTP addresses, that subclass is what you really have.
  5. getInputStream() gives the body as bytes. Wrapping it in an InputStreamReader with UTF-8 turns bytes into text, and BufferedReader reads it line by line.
  6. try-with-resources closes the stream; finally stops the local server.

The Shortcut: openStream

When you only need the body and no settings, url.openStream() is the same as url.openConnection().getInputStream():

Shortcut.java
try (InputStream in = URI.create(address).toURL().openStream()) {
    String text = new String(in.readAllBytes(), StandardCharsets.UTF_8);
}

It is convenient, but it gives you no timeouts, so it can wait forever. Prefer openConnection() with both timeouts set.

Other Protocols

URLConnection isn't only for HTTP. The same code reads a local file through a file: address, or a file inside a JAR through a jar: address. That is how Class.getResource(...) returns something you can read wherever the class was loaded from.

Common Mistakes

Setting a header after reading. Once the connection is made, setters throw IllegalStateException.

No timeouts. The defaults wait forever.

Converting bytes to text without a character set. Use the charset from Content-Type, or UTF-8, not the platform default.

Not closing the stream. The underlying connection can't be reused or released.

Practice

  1. Easy: Print every response header of the local server using getHeaderFields().
  2. Harder: Write a method download(URI from, Path to) that copies a resource to a file with Files.copy(inputStream, path), with both timeouts set.

Quick check: URLConnection

4 questions
1When is the request actually sent?
2What is the default read timeout?
3For an https address, what kind of object does openConnection() return?
4What happens if you call setRequestProperty after getInputStream?

Key Takeaways

Was this tutorial helpful?

Lesson 479 of 482