In this Java network programming tutorial, you will learn how to use the URLConnection and HttpURLConnection classes for developing Java programs that communicate to a server via URLs (mostly using HTTP protocol).
You will be able to write code for uploading and downloading files, web pages; sending and retrieving HTTP requests and responses; and the like.
URLConnection is the superclass of all classes that represent a connection between a Java application and a URL. The URLConnection class provides API for generic URLs, and its subclass HttpURLConnection provides additional support for HTTP-specific features.
Note that both of these classes are abstract - meaning that you can’t directly create new instances of URLConnection and HttpURLConnection. Instead, an instance of URLConnection is obtained by opening the connection from a URL object.
Typically, a client program communicates with a server via a URL follows this sequence of steps:
The steps 3 to 6 are optional, and the steps 5 and 6 are interchangeable.
Let’s explore the API of URLConnection and HttpURLConnection classes based on this sequence.
Simply create a new URL object for a given URL like this:
URL url = new URL("http://www.google.com");
This constructor will throw a MalformedURLException if the URL is malformed. This checked exception is a subclass of IOException.
A URLConnection instance is obtained by invoking the openConnection() method on the URL object:
URLConnection urlCon = url.openConnection();
If the protocol is http://, you can cast the returned object to an HttpURLConnection object:
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
Note that the openConnection() method doesn’t establish an actual network connection. It just returns an instance of URLConnection class.
The network connection is made explicitly when the connect() method is invoked, or implicitly when reading header fields or getting an input stream / output stream.
The URL’s openConnection() method throws IOException if an I/O error occurs.
Before actually establish the connection, you can configure various aspects that affect the ongoing communication between the client and the server, such as timeout, cache, HTTP request method, etc.
The URLConnection class provides the following methods for configuring the connection:
Note that these methods should be invoked before establishing the connection. Some methods throw IllegalStateException if the connection is already made.
In addition, the subclass HttpURLConnection provides the following methods for configuring the connection with HTTP-specific features:
The above methods are setters. And the URLConnection and HttpURLConnection classes also provide corresponding getters:
Once the connection is made, the server processes the URL request and sends back a response that consists of metadata and actual content. The metadata is a collection of key=value pairs which are called header fields.
The header fields reveal information about the server, status code, protocol information, etc. The actual content can be in text, HTML, image, etc. depending on the type of the document.
The URLConnection class provides the following methods for reading the header fields:
These are general methods for reading any header fields. And for some frequently-accessed header fields, the URLConnection class provides more specific methods:
And the subclass HttpURLConnection provides an additional method:
Note that when the header fields are read, the connection is implicitly established, without calling connect().
To read the actual content, you need to obtain an InputStream instance from the connection, and then use the InputStream’s read() methods to read the data:
InputStream inputStream = urlCon.getInputStream(); byte[] data = new byte[1024]; inputStream.read(data);
The InputStream’s read() is a low-level method that reads data to an array of bytes. So it is more convenient to wrap the InputStream in an InputStreamReader for reading data to characters:
InputStream inputStream = urlCon.getInputStream(); InputStreamReader reader = new InputStreamReader(inputStream); int character = reader.read(); // reads a single character char[] buffer = new char[4096]; reader.read(buffer); // reads to an array of characters
Or wrap the InputStream in a BufferedReader for reading data to Strings:
BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String line = reader.readLine(); // reads a line
Note that the getInputStream() method can throw the following exceptions:
To send data to the server, you have to enable output on the connection first:
urlCon.setDoOutput(true);
Then get the OutputStream object associated with the connection, and then use the OutputStream’s write() methods to write the data:
OutputStream outputStream = urlCon.getOutputStream(); byte[] data = new byte[1024]; outputStream.write(data);
As you can see, the OutputStream’s write() is a low-level method that writes an array of bytes. So it is more convenient to wrap the OutputStream in an OutputStreamWriter for writing characters:
OutputStreamWriter writer = new OutputStreamWriter(outputStream); int character = 'a'; writer.write(character); // writes a single character char[] buffer = new char[4096]; writer.write(buffer); // writes an array of characters
Or wrap the OutputStream in a PrintWriter for writing Strings:
PrintWriter writer = new PrintWriter(outputStream); String line = "This is String"; writer.print(line);
Note that the getOutputStream() method can throw IOException or UnknownServiceException.
To close the connection, invoke the close() method on either the InputStream or OutputStream object. Doing that may free the network resources associated with the URLConnection instance.
That’s about how to use the API of URLConnection and HttpURLConnection. Check the following articles for real-world examples:
So you can use URLConnection and HttpURLConnection for simple network programming, i.e. send and receive data to and from a server. I recommend you to read this book to learn more in-depth about Java network programming, or take this Java masterclass course to dive deep into Java programming.