Java
HTTP Request
Coding
Web Development
Programming

How to send HTTP request in Java?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Sending an HTTP request in Java is straightforward once you pick the right API. In modern Java, the built-in java.net.http.HttpClient is usually the best starting point because it supports a clean request builder, synchronous and asynchronous calls, and standard body handlers. Older APIs and third-party clients still exist, but you should understand why you are choosing them.

Use HttpClient for Modern Java Code

If you are on Java 11 or newer, the standard client is usually enough for common GET and POST requests.

A simple GET request looks like this.

java
1import java.io.IOException;
2import java.net.URI;
3import java.net.http.HttpClient;
4import java.net.http.HttpRequest;
5import java.net.http.HttpResponse;
6
7public class Main {
8    public static void main(String[] args) throws IOException, InterruptedException {
9        HttpClient client = HttpClient.newHttpClient();
10
11        HttpRequest request = HttpRequest.newBuilder()
12                .uri(URI.create("https://httpbin.org/get"))
13                .GET()
14                .build();
15
16        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
17
18        System.out.println(response.statusCode());
19        System.out.println(response.body());
20    }
21}

That example creates one client, builds a request, sends it, and reads the response body as a string. The code is small because the API handles the connection details for you.

Send JSON with a POST Request

For many real applications, the next step is sending JSON to an API.

java
1import java.io.IOException;
2import java.net.URI;
3import java.net.http.HttpClient;
4import java.net.http.HttpRequest;
5import java.net.http.HttpResponse;
6
7public class Main {
8    public static void main(String[] args) throws IOException, InterruptedException {
9        String json = "{\"name\":\"Ada\",\"role\":\"developer\"}";
10
11        HttpClient client = HttpClient.newHttpClient();
12        HttpRequest request = HttpRequest.newBuilder()
13                .uri(URI.create("https://httpbin.org/post"))
14                .header("Content-Type", "application/json")
15                .POST(HttpRequest.BodyPublishers.ofString(json))
16                .build();
17
18        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
19
20        System.out.println(response.statusCode());
21        System.out.println(response.body());
22    }
23}

The important part is not only .POST(...). It is also setting the Content-Type header so the server knows how to interpret the body.

Handle Errors Explicitly

A successful network call is not the same thing as a successful business response. HTTP status codes still matter.

A reliable pattern is:

  • send the request,
  • inspect statusCode(),
  • then decide whether the body represents success or failure for your application.

For example, a 404 or 500 still produces a valid HTTP response object. You should not treat that as the same as a network exception.

Timeouts and connectivity errors are different again. Those usually surface as thrown exceptions rather than normal responses.

Asynchronous Requests Are Built In

If you do not want to block the current thread, HttpClient also supports asynchronous sending with sendAsync.

java
1import java.net.URI;
2import java.net.http.HttpClient;
3import java.net.http.HttpRequest;
4import java.net.http.HttpResponse;
5
6public class Main {
7    public static void main(String[] args) {
8        HttpClient client = HttpClient.newHttpClient();
9        HttpRequest request = HttpRequest.newBuilder()
10                .uri(URI.create("https://httpbin.org/get"))
11                .GET()
12                .build();
13
14        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
15                .thenApply(HttpResponse::body)
16                .thenAccept(System.out::println)
17                .join();
18    }
19}

That pattern is useful when your application already works with asynchronous pipelines or wants to avoid blocking on network I/O.

When Older APIs Still Show Up

You will still see HttpURLConnection in older codebases. It works, but it is more verbose and less pleasant than HttpClient. Third-party libraries such as Apache HttpClient or OkHttp are also common when teams want advanced features, existing ecosystem integration, or a unified client across older Java versions.

So the real advice is not “only one way exists”. It is “start with the standard modern API unless your project has a specific reason to use something else”.

Common Pitfalls

  • Using HttpURLConnection in new Java code without a clear reason.
  • Forgetting to set Content-Type when sending JSON or form data.
  • Treating every returned response as success without checking the status code.
  • Confusing HTTP error responses with network exceptions.
  • Creating overly complex client code when the built-in HttpClient already fits the use case.

Summary

  • In modern Java, java.net.http.HttpClient is usually the best way to send HTTP requests.
  • Use HttpRequest builders for clear GET and POST definitions.
  • Check status codes separately from exception handling.
  • 'sendAsync is useful when you need non-blocking requests.'
  • Older clients still exist, but choose them for a reason, not by habit.

Course illustration
Course illustration

All Rights Reserved.