本ページはプロモーションが含まれています

Java入門

Java HttpClientとは?使い方を解説【2026年版】

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

「Javaで外部APIと通信したいけど、HttpClientかApache HttpClientか、それとも使い慣れたHttpURLConnectionのままでいいのか」。

この選択で一度は立ち止まったことがあるはずだ。

結論から言えば、Java 11以降であれば標準搭載のjava.net.http.HttpClientを選んで問題ない。

外部ライブラリを追加する手間なく、GETもPOSTも非同期処理も一通りこなせる。HTTP/2にも標準で対応している。

ただし、それだけでは終わらない。旧来のHttpURLConnectionから移行する際につまずくポイントが実はいくつかある。

この記事では、GETとPOSTの基本構文から、タイムアウトやヘッダーの設定、sendAsync()を使った非同期処理まで扱う。

さらに実際のAPI連携(天気APIの例)も、コードを動かしながら順に押さえていく。

HttpClientとは?

Java 11で標準搭載されたHttpClientの概要を示す図

まず、HttpClientがどのようなもので、どのような役割を担うのかを見ていきましょう。

HttpClientの概要と役割

HttpClientは、Java 11から標準APIとして導入された、HTTP通信を行うためのクライアントです。

このAPIの登場により、外部ライブラリに依存することなく、モダンなHTTP通信を実装できるようになりました。

HttpClientの主な役割は、指定したURLに対してHTTPリクエストを送信し、サーバーからのレスポンスを受信することです。

HTTP/1.1はもちろん、より高速なHTTP/2プロトコルにも標準で対応している点が大きな特長です。

同期処理だけでなく、ノンブロッキングI/Oを活かした非同期処理も簡単に行えます。

※ノンブロッキングI/O:データの入出力処理(I/O)が発生した際に、その処理の完了を待たずに(ブロックせずに)次の処理へ進むことができる方式のこと。

これにより、プログラムは待ち時間を有効活用し、全体の処理効率を高めることができます。

HttpURLConnectionとの違い

Javaには以前からHttpURLConnectionというクラスが存在しました。

しかし、HttpURLConnectionにはいくつかの課題がありました。

HttpClientは、これらの課題を解決するために設計された、後継のAPIと位置づけられます。主な違いは以下の表のとおりです。

機能HttpClient (Java 11〜)HttpURLConnection (Java 1.1〜)
APIの設計モダンで直感的(ビルダーパターン)古く、設定が煩雑
プロトコルHTTP/1.1, HTTP/2HTTP/1.1
通信方式同期、非同期の両方に対応同期(ブロッキングI/O)のみ
使いやすさシンプルで柔軟なリクエスト/レスポンス処理扱いにくく、定型的なコードが増えがち
依存性Java標準(外部ライブラリ不要)Java標準

これからJavaでHTTP通信を実装するならば、特別な理由がない限りHttpClientの利用が推奨されます。理由としてはAPIが使いやすく、現代的なアプリケーションに不可欠な非同期処理やHTTP/2に標準で対応しているからです。

JavaのHttpClientの基本構文

Java HttpClientの基本的な使い方(GET/POSTリクエスト)を示す図

それでは、具体的なjava http clientの使い方を見ていきましょう。基本的なGETリクエストとPOSTリクエストの例を紹介します。

HttpClientの作成方法

最初に、通信の主体となるHttpClientインスタンスを生成します。最も簡単な方法はnewHttpClient()メソッドを使うことです。

import java.net.http.HttpClient;

// HttpClientのインスタンスを生成
HttpClient client = HttpClient.newHttpClient();

この方法で生成されたインスタンスは、基本的な設定が適用されます。より詳細な設定を行いたい場合は、ビルダーパターンを用いて生成します。

import java.net.http.HttpClient;
import java.time.Duration;

// ビルダーを使ってHttpClientを生成
HttpClient client = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_2) // 使用するHTTPバージョンを指定
        .connectTimeout(Duration.ofSeconds(10)) // 接続タイムアウトを10秒に設定
        .build();

HttpClientインスタンスは不変でスレッドセーフです。

そのため、アプリケーション内で一つだけ生成し、それを複数のリクエストで使い回すことがパフォーマンス上推奨されています。

GETリクエストの基本例

GETリクエストは、ウェブページやAPIから情報を取得する際に最も一般的に使われるメソッドです。

HttpClientを使ったGETリクエストは、3つのステップで完了します。

  1. HttpRequestの作成: 送信するリクエスト情報を定義します。
  2. リクエストの送信: HttpClientを使ってリクエストを送信します。
  3. HttpResponseの処理: サーバーからのレスポンスを処理します。

以下に具体的なコードを示します。

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

public class GetExample {
    public static void main(String[] args) throws Exception {
        // 1. HttpClientのインスタンスを作成
        HttpClient client = HttpClient.newHttpClient();

        // 2. HttpRequestを作成 (GETリクエスト)
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.github.com/users/google"))
                .header("Accept", "application/vnd.github.v3+json")
                .GET() // GETメソッドを指定
                .build();

        // 3. リクエストを送信し、レスポンスを受信
        // BodyHandlers.ofString()はレスポンスボディを文字列として受け取る
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // レスポンスの情報を出力
        System.out.println("Status Code: " + response.statusCode());
        System.out.println("Response Body: " + response.body());
    }
}

このコードは、GitHubのAPIにGETリクエストを送信し、ユーザー情報を取得する例です。

HttpRequest.newBuilder()でリクエストの構築を開始し、uri()で行き先を指定し、GET()でメソッドを確定させています。

client.send()でリクエストが実行され、HttpResponseオブジェクトが返却されます。

あわせて読む

実務上の注意点として、BodyHandlers.ofString()はレスポンスボディ全体を一度にメモリへ読み込みます。

数MB程度のJSON APIなら問題ありません。

ただし画像やCSVなど大きめのファイルをダウンロードする用途では、メモリを圧迫してOutOfMemoryErrorの原因になりえます。

ファイルとして直接保存したい場合はBodyHandlers.ofFile(Path.of("output.bin"))を使います。

レスポンスをストリームのままディスクへ書き出せるため、メモリ使用量を一定に抑えられます。

POSTリクエストの送信例

POSTリクエストは、サーバーにデータを送信して新しいリソースを作成する際などに使用します。

例えば、フォームのデータを送信したり、JSON形式のデータをAPIに送信したりする場合です。

POSTリクエストでは、どのデータを送信するかBodyPublishersを使って指定する必要があります。

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

public class PostExample {
    public static void main(String[] args) throws Exception {
        // 送信するJSONデータ
        String json = "{\"name\":\"Taro Yamada\", \"job\":\"Developer\"}";

        // 1. HttpClientインスタンスを作成
        HttpClient client = HttpClient.newHttpClient();

        // 2. HttpRequestを作成 (POSTリクエスト)
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://httpbin.org/post"))
                .header("Content-Type", "application/json") // 送信するデータの種類を指定
                .POST(HttpRequest.BodyPublishers.ofString(json)) // POSTメソッドとリクエストボディを指定
                .build();

        // 3. リクエストを送信し、レスポンスを受信
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // レスポンスの情報を出力
        System.out.println("Status Code: " + response.statusCode());
        System.out.println("Response Body: " + response.body());
    }
}

GETリクエストとの主な違いは2点です。

主な違い

  • POST()メソッドを使用し、引数にHttpRequest.BodyPublishers.ofString(json)を指定して送信するデータ(リクエストボディ)を渡しています。
  • header()メソッドでContent-Typeapplication/jsonに指定し、送信するデータがJSON形式であることをサーバーに伝えています。

HttpClientのオプション設定

HttpClientのタイムアウト・ヘッダー・プロキシなどのオプション設定を示す図

HttpClientは、通信に関するさまざまなオプションを柔軟に設定できます。ここでは代表的な設定を3つ紹介します。

タイムアウトの設定方法

ネットワークの問題などでサーバーからの応答が長時間返ってこない場合、プログラムが停止してしまうのを防ぐためにタイムアウト設定は重要です。

HttpClientでは、接続タイムアウトを簡単に設定できます。

import java.net.http.HttpClient;
import java.time.Duration;

// 接続タイムアウトを10秒に設定
HttpClient client = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(10))
        .build();

connectTimeout()メソッドにjava.time.Durationオブジェクトを渡します。

指定した時間内に接続が確立されなかった場合、HttpConnectTimeoutExceptionがスローされます。

なお、connectTimeout()はHttpClient生成時に接続確立までの上限を設定するものです。

個々のリクエストごとにレスポンス待ちの上限を設定したい場合は、HttpRequest.Builder側のtimeout()メソッドを使います。

両者は役割が異なるため、用途に応じて使い分けます。

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://example.com"))
        .timeout(Duration.ofSeconds(5)) // このリクエスト単体のレスポンス待ち上限
        .GET()
        .build();

ヘッダーの追加方法

APIキーの指定やコンテンツタイプの指定など、リクエストヘッダーの追加は頻繁に行われます。

HttpRequest.Builderheader()メソッドを使えば簡単です。

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

// 複数のヘッダーを追加する例
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://example.com"))
        .header("X-API-KEY", "your_api_key_here") // カスタムヘッダー
        .header("Accept", "application/json")   // Acceptヘッダー
        .build();

同じキーでheader()メソッドを複数回呼び出すと、最後の値で上書きされます。複数の値を設定したい場合は、headers()メソッドを使用します。

リダイレクトの制御

リクエストしたURLが別のURLにリダイレクトされることがあります。

HttpClientのデフォルトの動作(NORMAL)では、安全なリダイレクト(例: HTTPからHTTPS)は自動的に追従します。

この動作はfollowRedirects()メソッドで変更可能です。

import java.net.http.HttpClient;

// リダイレクトポリシーを設定
HttpClient client = HttpClient.newBuilder()
        .followRedirects(HttpClient.Redirect.ALWAYS) // 常にリダイレクトに追従する
        .build();

// 他のポリシー
// HttpClient.Redirect.NEVER  - リダイレクトに追従しない
// HttpClient.Redirect.NORMAL - デフォルトの動作(同一プロトコルなど安全な場合のみ)

リダイレクトを一切許可しない場合はNEVER、HTTPからHTTPSへの変更などに関わらず常に追従させたい場合はALWAYSを指定します。

プロキシ設定

社内ネットワークなど、プロキシ経由でしか外部通信ができない環境では、HttpClientにプロキシを明示的に設定する必要があります。

ProxySelectorを使うことで、リクエストごとに個別指定しなくても、クライアント全体にプロキシ設定を適用できます。

import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.http.HttpClient;

// プロキシサーバーを明示的に指定
HttpClient client = HttpClient.newBuilder()
        .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 8080)))
        .build();

プロキシ側で認証が必要な場合は、authenticator()メソッドと組み合わせてAuthenticatorを設定する。

プロキシなしの環境をデフォルトとし、環境変数などで切り替える構成にしておくと、開発環境と本番環境の差異を吸収しやすい。

Cookieの管理

HttpClientはデフォルトではCookieを自動保持しない。

ログイン状態を維持したまま複数リクエストを送るような場合は、CookieManagerを明示的にセットする必要がある。

import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.http.HttpClient;

// Cookieを自動保持するHttpClientを生成
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);

HttpClient client = HttpClient.newBuilder()
        .cookieHandler(cookieManager)
        .build();

この設定をしておけば、レスポンスのSet-Cookieヘッダーが自動的に保存され、以降の同一クライアントでのリクエストに自動的に付与される。

セッション管理を伴うAPIやスクレイピング用途では実質必須の設定だ。

HttpClientを使った非同期処理

HttpClientによるsendAsync()を使った非同期処理の流れを示す図

HttpClientの強力な機能の一つが非同期処理です。

これにより、時間のかかる通信処理中にアプリケーションの他の処理をブロックすることなく、効率的なプログラムを記述できます。

sendAsync()で非同期通信を行う

非同期でリクエストを送信するには、send()の代わりにsendAsync()メソッドを使用します。

send()HttpResponseを直接返すのに対し、sendAsync()CompletableFuture<HttpResponse>を返します。

CompletableFutureは、まだ完了していない非同期処理の結果を保持するコンテナのようなものです。

同期処理と非同期処理でプログラムの流れがどう変わるかを図にすると、次のようになります。

sequenceDiagram participant M as メインスレッド participant S as サーバー Note over M,S: send()(同期)の場合 M->>S: リクエスト送信 activate M S-->>M: レスポンス(待機) deactivate M M->>M: 次の処理へ Note over M,S: sendAsync()(非同期)の場合 M->>S: リクエスト送信 M->>M: 即座に次の処理へ S-->>M: レスポンス<br>(thenAccept等で処理)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

public class AsyncExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.github.com/"))
                .build();

        // 非同期でリクエストを送信
        CompletableFuture<HttpResponse<String>> future = 
            client.sendAsync(request, HttpResponse.BodyHandlers.ofString());

        System.out.println("リクエストを送信しました。レスポンスを待っています...");

        // レスポンスが返ってきた後の処理を定義
        future.thenAccept(response -> {
            System.out.println("Status Code: " + response.statusCode());
            System.out.println("Response Body: " + response.body().substring(0, 80) + "...");
        });

        // 非同期処理の完了を待つ (サンプルコードのため)
        future.join();
    }
}

sendAsync()を呼び出すと、リクエストはバックグラウンドスレッドで実行され、プログラムは即座に次の行に進みます。

これにより、ユーザーインターフェースが固まったり、他の処理が待たされたりするのを防ぐことができます。

CompletableFutureとの組み合わせ方

CompletableFutureの真価は、非同期処理の結果に対して連続的な処理を定義できる点にあります。

  • thenApply(): 結果を受け取り、変換して別のCompletableFutureを返す(例: レスポンスボディの文字列をJSONオブジェクトに変換する)。
  • thenAccept(): 結果を受け取って消費する(例: 画面に表示する)。返り値はない。
  • thenRun(): 結果に関係なく、処理完了後に特定のRunnableを実行する。
  • exceptionally(): 例外が発生した場合の処理を定義する。
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

public class CompletableFutureChain {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.github.com/users/google"))
                .build();

        CompletableFuture<Void> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body) // HttpResponseからボディ(文字列)を抽出
                .thenApply(body -> { // ボディを加工 (ここでは大文字に変換)
                    System.out.println("ボディを大文字に変換します。");
                    return body.toUpperCase();
                })
                .thenAccept(processedBody -> { // 加工後のボディをコンソールに出力
                    System.out.println("処理結果:");
                    System.out.println(processedBody.substring(0, 100) + "...");
                })
                .exceptionally(e -> { // エラーハンドリング
                    System.err.println("エラーが発生しました: " + e.getMessage());
                    return null;
                });

        System.out.println("非同期処理のチェーンを定義しました。");
        
        // 処理の完了を待機
        future.join();
    }
}

このようにメソッドチェーンを使うことで、非同期処理の各ステップを宣言的かつ直感的に記述できます。

あわせて読む

HttpClientの活用例

HttpClientを使った天気APIとの通信・JSONパースの活用例を示す図

HttpClientはさまざまな場面で活用できます。ここでは、特に一般的な2つの活用例を見ていきましょう。

API通信での利用(例:天気API)

多くのWebサービスが、外部からデータを取得するためのAPIを公開しています。

ここでは、無料で利用できる気象API「Open-Meteo」を使って、東京の現在の天気を取得する例を紹介します。

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

public class WeatherApiExample {
    public static void main(String[] args) throws Exception {
        // 東京の緯度経度を指定してAPIのURLを構築
        String apiUrl = "https://api.open-meteo.com/v1/forecast" +
                "?latitude=35.6895&longitude=139.6917¤t_weather=true";

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(apiUrl))
                .GET()
                .build();

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

        if (response.statusCode() == 200) {
            System.out.println("東京の現在の天気情報:");
            System.out.println(response.body());
        } else {
            System.out.println("天気情報の取得に失敗しました。Status Code: " + response.statusCode());
        }
    }
}

APIの仕様に従ってURLを組み立て、GETリクエストを送信するだけで、簡単に外部サービスのデータを利用できます。

あわせて読む

JSONレスポンスのパース(Jackson/Gson連携)

APIから返されるデータの多くはJSON形式です。

受け取ったJSON文字列をそのまま扱うのは不便なため、通常はJavaのオブジェクトに変換(パースまたはデシリアライズ)します。

この変換には、JacksonGsonといったライブラリがよく利用されます。ここではJacksonを使った例を示します。

build.gradlepom.xmlJacksonライブラリの依存関係を追加する必要があります)

まず、JSONの構造に対応するJavaクラス(POJO)を定義します。

// CurrentWeather.java
// APIレスポンスの"current_weather"部分に対応するクラス
public class CurrentWeather {
    public double temperature;
    public double windspeed;
    public int weathercode;
}

次に、HttpClientで受け取ったレスポンスボディをJacksonでパースします。

import com.fasterxml.jackson.databind.ObjectMapper;
// (他のimport文は省略)

public class JsonParseExample {
    public static void main(String[] args) throws Exception {
        // (APIリクエスト部分は前の例と同じ)
        String apiUrl = "..."; // 天気APIのURL
        // ... request, responseの取得 ...
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() == 200) {
            String responseBody = response.body();

            // JacksonのObjectMapperを生成
            ObjectMapper mapper = new ObjectMapper();

            // JSON文字列をパースしてJavaオブジェクトに変換
            // ここではレスポンス全体から"current_weather"ノードを抽出してパース
            CurrentWeather weather = mapper.readTree(responseBody)
                                            .get("current_weather")
                                            .traverse(mapper)
                                            .readValueAs(CurrentWeather.class);
            
            System.out.println("現在の気温: " + weather.temperature + "℃");
            System.out.println("現在の風速: " + weather.windspeed + " km/h");
            System.out.println("天気コード: " + weather.weathercode);
        }
    }
}

このようにライブラリと組み合わせることで、HttpClientで取得したデータを効率的に扱えます。

あわせて読む

HttpClient利用時の注意点

HttpClient利用時に注意すべきバージョン互換性・スレッド安全性を示す図

HttpClientは非常に便利ですが、利用する上で知っておくべき点がいくつかあります。

HttpClientとOkHttpはどちらを選ぶべきか

Java標準のHttpClientには外部ライブラリ不要という利点があります。

ただし実務ではOkHttpやApache HttpClient 5系が使われているプロジェクトも依然として多くあります。判断基準はシンプルです。

新規プロジェクトで外部依存を増やしたくない場合、あるいは学習コストを抑えたい場合はHttpClientで十分こと足ります。

一方、インターセプター(リクエスト/レスポンスの共通処理を差し込む仕組み)を多用する既存プロジェクトもあります。

Retrofitのような上位ライブラリと組み合わせて使う場合は、エコシステムが成熟しているOkHttpのほうが結果的に書くコード量が少なくなることが多いです。

「標準APIだから常に正解」というわけではなく、既存のチーム標準やライブラリ構成との整合性も含めて選ぶのが実務的な判断です。

バージョンと互換性(Java 11以上)

java.net.http.HttpClientは、Java 11で正式に導入されたAPIです。

そのため、Java 8やJava 10といった古いバージョンでは利用できません。プロジェクトで使用しているJavaのバージョンを必ず確認してください。

なお、JDK 21以降ではHttpClientがAutoCloseableを実装しています。

明示的にclose()shutdown()でリソースを解放できるようになりました。

2026年時点の最新LTSであるJava 25でも、本記事のAPIはそのまま利用できます。

もし古いバージョンで同様の機能が必要な場合は、Apache HttpClientやOkHttpといった外部ライブラリを検討する必要があります。

スレッド安全性と再利用のポイント

HttpClientインスタンスは、不変(immutable)であり、スレッドセーフに設計されています。

これは、複数のスレッドから同時に同じインスタンスを使っても問題が発生しないことを意味します。

リクエストごとにHttpClient.newHttpClient()を呼び出して新しいインスタンスを生成するのは非効率です。

HttpClientは内部で接続プールなどのリソースを管理しているため、インスタンスを生成するコストは決して小さくありません。

アプリケーションの起動時にHttpClientインスタンスを一つだけ生成し、それをアプリケーション全体で共有して使い回すのがベストプラクティスです。

// アプリケーションで共有するHttpClientインスタンス
public class AppHttpClient {
    public static final HttpClient INSTANCE = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    private AppHttpClient() {}
}

// 利用する側のコード
public class SomeService {
    public void doSomething() throws Exception {
        HttpRequest request = ...;
        // 共有インスタンスを使ってリクエストを送信
        HttpResponse<String> response = AppHttpClient.INSTANCE.send(request, HttpResponse.BodyHandlers.ofString());
    }
}

なお、JDK 21以降であればHttpClientをtry-with-resourcesで扱うことも可能になった。

ただしアプリケーション全体で使い回す共有インスタンスの場合は、リクエストのたびにcloseする必要はない。

close()はアプリケーション終了時など、明示的にクライアントを破棄するタイミングでのみ呼び出せば十分だ。

例外処理(IOException/InterruptedException)

ここまでのサンプルコードはmainメソッドにthrows Exceptionを付けて例外を丸ごと外側へ投げていた。

学習用にはそれで構わないが、実際のアプリケーションコードではこの書き方は避けたい。client.send()は主に2種類の検査例外を投げる。

  • IOException: 接続失敗・タイムアウト・DNS解決エラーなど、通信経路上の問題で発生する。
  • InterruptedException: リクエスト送信中にスレッドが割り込みを受けた場合に発生する。
try {
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println(response.body());
} catch (IOException e) {
    // 通信エラー:リトライやフォールバック処理を検討
    System.err.println("通信に失敗しました: " + e.getMessage());
} catch (InterruptedException e) {
    // 割り込み:スレッドの割り込み状態を復元してから再スロー
    Thread.currentThread().interrupt();
    throw new RuntimeException("リクエストが中断されました", e);
}

InterruptedExceptionをキャッチしたときに何もせず握りつぶすと、スレッドの割り込みシグナルが失われてしまう。

Thread.currentThread().interrupt()で割り込み状態を復元しておくのが定石だ。

あわせて読む

よくある質問(FAQ)

Q1. HttpClientとHttpURLConnectionはどちらを使うべきですか?

Java 11以降のプロジェクトであれば、特別な理由がない限りHttpClientを選んでください。ビルダーパターンで直感的に書け、HTTP/2や非同期処理にも標準対応しています。HttpURLConnectionは後方互換のために残っているレガシーAPIという位置づけです。

Q2. Java 8でもHttpClientは使えますか?

標準のjava.net.http.HttpClientはJava 11以降でのみ利用できます。Java 8環境で同様の機能が必要な場合は、Apache HttpClientやOkHttpといった外部ライブラリを検討してください。

Q3. GETとPOSTの実装で何が変わりますか?

基本構造は同じです。POSTではHttpRequest.Builderheader("Content-Type", ...)でデータ種別を指定し、POST(HttpRequest.BodyPublishers.ofString(json))で送信するボディを渡す点が異なります。GETはGET()のみでボディ指定は不要です。

Q4. 非同期処理(sendAsync)はどんな場面で使うべきですか?

複数のAPIを並行して呼び出したい場合や、UIスレッドを止めたくないアプリケーションで有効です。単純なバッチ処理やCLIツールなど、順番に結果が必要な場合はsend()で同期的に書いたほうがコードがシンプルになります。

Q5. HttpClientインスタンスは毎回生成すべきですか?

いいえ。HttpClientは不変でスレッドセーフなため、アプリケーション起動時に一つだけ生成し、使い回すのがベストプラクティスです。リクエストのたびに生成すると接続プールの再構築コストがかかります。

Q6. タイムアウトはどこで設定すればいいですか?

接続確立までの上限はHttpClient.Builder.connectTimeout()で設定します。個々のリクエストのレスポンス待ち上限はHttpRequest.Builder.timeout()で設定します。役割が異なるため、両方を組み合わせて使うのが安全です。

まとめ

この記事では、Java 11から標準となったHttpClientについて、基本的な使い方から応用までを解説しました。

2026年時点の最新LTSであるJava 25でも同じAPIがそのまま使えるため、ここで紹介したコードは長く使い回せます。

HttpClientの利点と活用場面

HttpClientの利点は明確です。

  • 標準API: 外部ライブラリを追加する手間がありません。
  • モダンな機能: HTTP/2や非同期処理に標準で対応しています。
  • シンプルなAPI: ビルダーパターンにより、直感的で読みやすいコードを記述できます。
  • 柔軟性: タイムアウトやリダイレクトなど、詳細な設定が可能です。

Web APIとの通信、マイクロサービス間の連携、Webスクレイピングなど。

現代のJavaアプリケーション開発におけるHTTP通信の場面では、HttpClientが第一の選択肢となるでしょう。

HttpClientを使いこなせば、Javaでの開発がより一層スムーズで楽しいものになります。ぜひ、あなたのプロジェクトで活用してみてください。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

-Java入門