Java - Java Networking with URL and HTTP Connections

Java provides built-in networking classes that allow applications to communicate with resources available on the internet or within a network. One important part of Java networking is working with URLs and HTTP connections. A URL identifies the location of a resource, while an HTTP connection allows a Java program to communicate with a web server and exchange data.

1. Understanding URL in Java

URL stands for Uniform Resource Locator. It specifies the address of a resource on the internet. A URL can point to a webpage, image, text file, API endpoint, or another online resource.

A typical URL looks like this:

https://www.example.com/products?id=101

A URL can contain several components:

https://www.example.com:443/products?id=101#details

Here:

  • https is the protocol.

  • www.example.com is the host.

  • 443 is the port number.

  • /products is the path.

  • id=101 is the query parameter.

  • #details is the fragment.

Java provides the java.net.URL class for representing and examining URLs.

Example:

import java.net.URL;

public class URLExample {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://www.example.com/products?id=101");

        System.out.println("Protocol: " + url.getProtocol());
        System.out.println("Host: " + url.getHost());
        System.out.println("Port: " + url.getPort());
        System.out.println("Path: " + url.getPath());
        System.out.println("Query: " + url.getQuery());
    }
}

The URL class provides methods such as getProtocol(), getHost(), getPort(), getPath(), and getQuery() for accessing different parts of a URL.

2. Opening a Connection Using URL

A URL object can be used to establish a connection to the resource it represents. The openConnection() method creates a connection object.

Example:

import java.net.URL;
import java.net.URLConnection;

public class ConnectionExample {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://www.example.com");

        URLConnection connection = url.openConnection();

        System.out.println("Content Type: " + connection.getContentType());
        System.out.println("Content Length: " + connection.getContentLengthLong());
    }
}

URLConnection provides a general mechanism for communicating with resources identified by URLs. It can be used to retrieve information such as content type, content length, and headers.

The connection does not necessarily mean that data has already been transferred. The actual communication generally occurs when the connection is connected or when its input/output streams are accessed.

3. HTTP Connections

HTTP stands for Hypertext Transfer Protocol. It is one of the primary protocols used for communication between web clients and web servers.

For example, when a Java application sends a request to a web server, the server processes the request and returns an HTTP response.

An HTTP interaction generally contains:

Java Application
       |
       | HTTP Request
       v
   Web Server
       |
       | HTTP Response
       v
Java Application

The request can contain information such as the HTTP method, URL, headers, and request body. The response usually contains a status code, headers, and response body.

Java provides HttpURLConnection for traditional HTTP communication.

4. Using HttpURLConnection

HttpURLConnection extends URLConnection and provides HTTP-specific functionality.

Example:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpExample {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://example.com");

        HttpURLConnection connection =
                (HttpURLConnection) url.openConnection();

        connection.setRequestMethod("GET");

        int statusCode = connection.getResponseCode();

        System.out.println("Status Code: " + statusCode);

        BufferedReader reader = new BufferedReader(
                new InputStreamReader(connection.getInputStream())
        );

        String line;

        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }

        reader.close();
        connection.disconnect();
    }
}

In this example, the program creates a URL, opens an HTTP connection, specifies the GET method, obtains the response status code, and reads the response body.

5. HTTP GET Request

The GET method is commonly used to retrieve information from a server.

For example:

GET /products/101

A Java application can send a GET request using HttpURLConnection.

URL url = new URL("https://example.com/products/101");

HttpURLConnection connection =
        (HttpURLConnection) url.openConnection();

connection.setRequestMethod("GET");

int status = connection.getResponseCode();

System.out.println(status);

A successful request commonly returns a status code such as 200.

GET requests can also contain query parameters:

https://example.com/products?id=101&category=books

The query parameters are sent as part of the URL.

6. HTTP POST Request

The POST method is generally used when a client needs to send data to a server.

For example, an application might send user information to a web server.

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

public class PostExample {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://example.com/users");

        HttpURLConnection connection =
                (HttpURLConnection) url.openConnection();

        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
        connection.setRequestProperty(
                "Content-Type",
                "application/json"
        );

        String json = "{\"name\":\"John\",\"age\":25}";

        try (OutputStream output = connection.getOutputStream()) {
            output.write(json.getBytes(StandardCharsets.UTF_8));
        }

        System.out.println(
                "Response Code: " + connection.getResponseCode()
        );

        connection.disconnect();
    }
}

The setDoOutput(true) method allows the application to send data through the connection. The Content-Type header tells the server what type of data is being transmitted.

7. HTTP Headers

HTTP headers contain additional information about a request or response.

Examples include:

Content-Type
Accept
Authorization
User-Agent
Content-Length

Java can set request headers using setRequestProperty().

connection.setRequestProperty(
    "Accept",
    "application/json"
);

The application can also read response headers:

String contentType = connection.getHeaderField("Content-Type");

System.out.println(contentType);

Headers are important when communicating with web services because servers often use them to determine how requests should be processed.

8. HTTP Response Codes

HTTP servers use status codes to indicate the result of a request.

Some common status codes are:

Status Code Meaning
200 OK
201 Created
204 No Content
301 Moved Permanently
302 Found/Redirect
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
500 Internal Server Error
503 Service Unavailable

Java applications can retrieve the status code using:

int status = connection.getResponseCode();

Applications should check this value before attempting to process the response.

9. Reading Server Responses

The response body can be accessed through an input stream.

BufferedReader reader = new BufferedReader(
    new InputStreamReader(connection.getInputStream())
);

String line;

while ((line = reader.readLine()) != null) {
    System.out.println(line);
}

reader.close();

The returned content could be HTML, JSON, XML, plain text, or another format.

For an unsuccessful HTTP response, applications may need to read from the error stream:

BufferedReader reader = new BufferedReader(
    new InputStreamReader(connection.getErrorStream())
);

This helps applications understand why a request failed.

10. Timeouts

Network operations can sometimes take a long time because of slow servers or network problems. Java allows developers to specify connection and read timeouts.

connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);

Here, 5000 represents 5,000 milliseconds, or 5 seconds.

A connection timeout controls how long the application waits while establishing the connection. A read timeout controls how long it waits for data after the connection has been established.

Timeouts are important because they prevent an application from waiting indefinitely for a network operation.

11. URLConnection vs HttpURLConnection

URLConnection is a general-purpose class for communicating with resources identified by URLs.

HttpURLConnection is specifically designed for HTTP communication.

The relationship can be represented as:

URLConnection
     |
     v
HttpURLConnection

HttpURLConnection provides HTTP-specific operations such as:

setRequestMethod()
getResponseCode()
getResponseMessage()
getHeaderField()

Therefore, when communicating specifically with HTTP or HTTPS servers, HttpURLConnection provides functionality beyond the general URLConnection class.

12. Modern Java HTTP Client

Modern Java applications can use the java.net.http.HttpClient API instead of the older HttpURLConnection approach. The HTTP Client API was introduced as an incubating API in Java 9 and became a standard API in Java 11.

A simple GET request can be written as:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ModernHttpExample {
    public static void main(String[] args) throws Exception {

        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://example.com"))
                .GET()
                .build();

        HttpResponse<String> response =
                client.send(
                        request,
                        HttpResponse.BodyHandlers.ofString()
                );

        System.out.println("Status: " + response.statusCode());
        System.out.println("Body: " + response.body());
    }
}

This API provides a cleaner approach to HTTP communication and also supports asynchronous requests, HTTP/2, configurable clients, request bodies, response handlers, and other modern networking features.

13. Synchronous and Asynchronous HTTP Requests

With the modern HttpClient, a request can be performed synchronously using send().

HttpResponse<String> response =
        client.send(
                request,
                HttpResponse.BodyHandlers.ofString()
        );

The application waits until the operation finishes.

For asynchronous communication, sendAsync() can be used:

client.sendAsync(
        request,
        HttpResponse.BodyHandlers.ofString()
).thenAccept(response -> {
    System.out.println(response.body());
});

This allows the application to continue performing other work while the network request is in progress.

14. Important Points

Java networking with URLs and HTTP connections is useful whenever an application needs to communicate with web servers or online resources. The URL class represents a resource address, while URLConnection provides general connection functionality. HttpURLConnection adds HTTP-specific capabilities, including HTTP methods, status codes, headers, and request and response handling.

For modern Java development, the java.net.http.HttpClient API is generally the preferred standard-library approach for HTTP communication. Understanding both the traditional HttpURLConnection model and the modern HTTP Client API is useful because existing Java applications may still use the older API.

Conclusion

Java provides powerful built-in facilities for network communication. URL handling allows applications to identify and inspect internet resources, while HTTP APIs enable applications to send requests and process server responses. Developers can work with GET and POST requests, headers, status codes, request bodies, response streams, timeouts, and asynchronous operations.

These capabilities are fundamental when developing Java applications that communicate with websites, REST APIs, web services, cloud applications, and other network-based systems.