Java
HTTP response code
URL
Programming
Networking

How to get HTTP response code for a URL in Java?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Getting the HTTP status code for a URL in Java is straightforward, but the preferred API depends on your Java version. On modern JDKs, HttpClient is the cleanest option. On older codebases, HttpURLConnection is still common.

Modern Java: HttpClient

If you are on Java 11 or later, use java.net.http.HttpClient.

java
1import java.net.URI;
2import java.net.http.HttpClient;
3import java.net.http.HttpRequest;
4import java.net.http.HttpResponse;
5import java.time.Duration;
6
7public class StatusCheck {
8    public static int getStatusCode(String url) throws Exception {
9        HttpClient client = HttpClient.newBuilder()
10                .connectTimeout(Duration.ofSeconds(5))
11                .build();
12
13        HttpRequest request = HttpRequest.newBuilder()
14                .uri(URI.create(url))
15                .timeout(Duration.ofSeconds(10))
16                .GET()
17                .build();
18
19        HttpResponse<Void> response =
20                client.send(request, HttpResponse.BodyHandlers.discarding());
21
22        return response.statusCode();
23    }
24
25    public static void main(String[] args) throws Exception {
26        System.out.println(getStatusCode("https://example.com"));
27    }
28}

BodyHandlers.discarding() is useful when you only need the status and do not want to store the response body.

Legacy-Compatible Java: HttpURLConnection

If you are working on older Java versions, HttpURLConnection still works.

java
1import java.io.IOException;
2import java.net.HttpURLConnection;
3import java.net.URL;
4
5public class LegacyStatusCheck {
6    public static int getStatusCode(String url) throws IOException {
7        HttpURLConnection connection =
8                (HttpURLConnection) new URL(url).openConnection();
9
10        connection.setRequestMethod("GET");
11        connection.setConnectTimeout(5000);
12        connection.setReadTimeout(10000);
13        connection.setInstanceFollowRedirects(true);
14
15        return connection.getResponseCode();
16    }
17}

This is still widely seen in existing codebases, but for new code HttpClient is usually better.

Use HEAD When You Only Need Status

If the server supports it, HEAD can be lighter than GET because it asks for headers without the body.

Modern Java:

java
1HttpRequest request = HttpRequest.newBuilder()
2        .uri(URI.create("https://example.com"))
3        .method("HEAD", HttpRequest.BodyPublishers.noBody())
4        .timeout(Duration.ofSeconds(5))
5        .build();

That said, not every endpoint handles HEAD correctly. If you get strange behavior, fall back to GET.

Redirect Policy Matters

Some URLs reply with redirects rather than a final content status. Decide whether you want the original redirect code or the status after following the redirect chain.

With HttpClient, that behavior is configurable:

java
HttpClient client = HttpClient.newBuilder()
        .followRedirects(HttpClient.Redirect.NORMAL)
        .build();

If you leave redirect handling unspecified, your observed status code may not match your operational expectation.

Distinguish HTTP Errors from Network Errors

This is an important design point:

  • '404, 500, and 503 are valid HTTP responses'
  • DNS failures, timeouts, and SSL problems are exceptions

A method that fetches status codes should normally return the HTTP status for valid responses and only throw when the request itself could not be completed.

That distinction makes retry logic and observability much cleaner.

Check Ranges, Not Only 200

Many valid endpoints return statuses other than 200, such as:

  • '201 Created'
  • '204 No Content'
  • '301 Moved Permanently'

So your application logic may want range checks:

java
public static boolean isSuccess(int statusCode) {
    return statusCode >= 200 && statusCode < 300;
}

Or for broader health checks:

java
public static boolean isHealthy(int statusCode) {
    return statusCode >= 200 && statusCode < 400;
}

The correct rule depends on your use case.

Async Example

If you are checking many URLs, asynchronous requests can help reduce thread blocking.

java
1import java.util.concurrent.CompletableFuture;
2
3CompletableFuture<Integer> future = client
4        .sendAsync(request, HttpResponse.BodyHandlers.discarding())
5        .thenApply(HttpResponse::statusCode);
6
7int code = future.join();

This is useful for monitoring or batched endpoint probes.

Common Pitfalls

Forgetting timeouts can make the program hang far longer than intended on slow or broken networks.

Treating only 200 as success can reject perfectly valid responses such as 204.

Confusing transport failures with HTTP status failures makes logging and retry behavior harder to reason about.

Using HEAD everywhere without checking server support can lead to misleading failures on endpoints that do not implement it properly.

Summary

  • Use HttpClient on Java 11 and later for the cleanest status-code lookup.
  • Use HttpURLConnection only when you need older-runtime compatibility.
  • Set explicit connect and read timeouts.
  • Use BodyHandlers.discarding() if you only need headers and status.
  • Treat HTTP error codes and network exceptions as different categories of failure.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.