1. 概要

このチュートリアルでは、JavaHttpClientを使用してHTTPSURLに接続する方法について説明します。 また、有効なSSL証明書を持たないURLでクライアントを使用する方法についても学習します。

古いバージョンのJavaでは、サーバーへの接続にApacheHTTPClientやOkHttpなどのライブラリを使用することをお勧めしました。 Java 11では、改良されたHttpClientライブラリがJDKに追加されました。 これを使用してSSL経由でサービスを呼び出す方法を見てみましょう。

2. JavaHttpClientを使用したHTTPSURLの呼び出し

テストケースを使用してクライアントコードを実行します。 テストの目的で、HTTPSで実行される既存のURLを使用します。

クライアントをセットアップしてサービスを呼び出すコードを書いてみましょう。

HttpClient httpClient = HttpClient.newHttpClient();
    
HttpRequest request = HttpRequest.newBuilder()
  .uri(URI.create("https://www.google.com/"))
  .build();

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

ここでは、最初に HttpClient.newHttpClient()メソッドを使用してクライアントを作成しました。 次に、リクエストを作成し、ヒットするサービスのURLを設定しました。 最後に、 HttpClient.send()メソッドを使用してリクエストを送信し、応答を収集しました–Stringとして応答本文を含むHttpResponseオブジェクト。

上記のコードをテストケースに入れて以下のアサーションを実行すると、次のように合格することがわかります。

assertEquals(200, response.statusCode());

3. 無効なHTTPSURLを呼び出す

それでは、URLを有効なSSL証明書を持たない別のURLに変更しましょう。 これを行うには、リクエストオブジェクトを変更します。

HttpRequest request = HttpRequest.newBuilder()
  .uri(new URI("https://www.testingmcafeesites.com/"))
  .build();

テストを再度実行すると、次のエラーが発生します。

Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching www.testingmcafeesites.com found.
  at java.base/sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:212)
  at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:103)

これは、URLに有効なSSL証明書がないためです。

4. SSL証明書検証のバイパス

上記のエラーを解決するために、SSL証明書の検証をバイパスするソリューションを見てみましょう。

Apache HttpClientでは、クライアントをバイパス証明書検証に変更できます。 ただし、JavaHttpClientではそれを行うことはできません。 ホスト名の検証を無効にするには、JVMに変更を加える必要があります。

これを行う1つの方法は、Webサイトの証明書をJavaKeyStoreにインポートすることです。 これは一般的な方法であり、信頼できる内部Webサイトが少数ある場合に適したオプションです。

ただし、Webサイトの数が多い場合や環境が多すぎて管理できない場合は、これが面倒になる可能性があります。 この場合、プロパティjdk.internal.httpclient.disableHostnameVerificationを使用して、ホスト名の検証を無効にすることができます。

アプリケーションをコマンドライン引数として実行するときに、このプロパティを設定できます

java -Djdk.internal.httpclient.disableHostnameVerification=true -jar target/java-httpclient-ssl-0.0.1-SNAPSHOT.jar

または、クライアントを作成する前に プログラムでこのプロパティを設定することもできます

Properties props = System.getProperties();
props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());

HttpClient httpClient = HttpClient.newHttpClient();

ここでテストを実行すると、合格していることがわかります。

プロパティを変更すると、すべてのリクエストで証明書の検証が無効になることに注意してください。 これは、特に本番環境では望ましくない場合があります。ただし、このプロパティを非-本番環境。

5. SpringでJavaHttpClientを使用できますか?

Springは、HTTPリクエストを作成するための2つの一般的なインターフェイスを提供します。

  • 同期リクエストの場合はRestTemplate
  • 同期および非同期要求の場合はWebClient

どちらも、Apache HttpClient、OkHttp、古いHttpURLConnectionなどの一般的なHTTPクライアントと一緒に使用できます。 ただし、これらの2つのインターフェイスにJavaHttpClientを接続することはできません。 それはむしろそれらの代替として見られています。

Java HttpClientを使用して、同期および非同期の要求を作成したり、要求と応答を変換したり、タイムアウトを追加したりできます。 したがって、Springのインターフェースを必要とせずに直接利用できます。

6. 結論

この記事では、JavaHTTPクライアントを使用してSSLを必要とするサーバーに接続する方法について説明しました。 また、有効な証明書を持たないURLでクライアントを使用する方法についても検討しました。

いつものように、これらの例のコードはGitHubから入手できます。