概要
外部 API との連携やマイクロサービス間通信など、業務システムで HTTP リクエストを送信する場面は日常的に発生します。Java 11 で追加された HttpClient は、それまでの HttpURLConnection と比べてビルダーパターンで直感的に組み立てられ、タイムアウト設定やレスポンス処理も簡潔です。ただし Java 8 環境ではこの API が使えないため、HttpURLConnection との使い分けを理解しておく必要があります。この記事では、HttpClient による GET/POST の基本パターンから、ステータスコードの判定、接続・読み取りタイムアウトの設定、Java 21 での非同期処理まで、実務で必要になるポイントを整理します。
使いどころ
外部 REST API から JSON データを取得し、業務システムのマスタ情報を更新する
決済サービスの API に POST リクエストで注文情報を送信し、レスポンスを処理する
複数の外部 API を並行して呼び出し、レスポンスを集約してダッシュボードに表示する
コード例
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.time.Duration;
import java.io.IOException;
public class HttpClientSample {
private static final HttpClient CLIENT = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.build();
public static String get(String url) throws IOException, InterruptedException {
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofSeconds(10))
.header("Accept", "application/json")
.GET()
.build();
var response = CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IOException("HTTP エラー: " + response.statusCode());
}
return response.body();
}
public static String post(String url, String jsonBody)
throws IOException, InterruptedException {
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofSeconds(10))
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
var response = CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IOException("HTTP エラー: " + response.statusCode());
}
return response.body();
}
public static void main(String[] args) throws IOException, InterruptedException {
String body = get("https://httpbin.org/get");
System.out.println(body);
String json = "{\"name\":\"太郎\",\"age\":25}";
String result = post("https://httpbin.org/post", json);
System.out.println(result);
}
}Version Coverage
HttpClient のビルダーパターンと var を組み合わせて簡潔に記述できる。同期送信が基本パターン。
// Java 17: HttpClient で GET(簡潔)
private static final HttpClient CLIENT =
HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.build();
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofSeconds(10))
.header("Accept", "application/json")
.GET().build();
var response = CLIENT.send(request,
HttpResponse.BodyHandlers.ofString());Library Comparison
注意点
HttpClient は Java 11 以降でのみ使用可能。Java 8 環境では HttpURLConnection を使うこと
HttpClient インスタンスはスレッドセーフなので、static final で共有して使い回すのが効率的。リクエストごとに new しない
connectTimeout はサーバーへの接続確立の制限時間、request の timeout はレスポンス全体の制限時間。両方を適切に設定すること
ステータスコード 2xx 以外をエラーとして扱う場合、HttpClient は例外を投げないため自分で判定ロジックを書く必要がある
FAQ
Java 11 以降であれば HttpClient を選んでください。ビルダーパターンで組み立てやすく、非同期処理もサポートしています。Java 8 環境では HttpURLConnection を使います。
HttpRequest.newBuilder().header("Authorization", "Bearer xxx") のように header メソッドをチェーンします。複数ヘッダーは header を繰り返すか headers メソッドで一括指定します。
connectTimeout は 3〜5 秒、request の timeout は API の応答特性に応じて 10〜30 秒が目安です。バッチ処理では長めに、画面応答では短めに設定します。