SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Java 11の変更点と新しいAPI

HTTP Client APIでの接続カスタマイズからWebSocketでの接続まで行う

Java 11の変更点と新しいAPI 第2回

HTTP Client APIの多様な利用方法

 簡単なリクエスト処理の実行であれば前回紹介した内容だけでほとんどカバーできると思いますが、HTTP2やWebSocket等での機能を求める理由として、リアルタイム性が高い機能が望まれる場合が多くあります。

 その場合には、リクエスト処理と受信したデータの処理を同期的に処理することが少なくなり、APIを実行する際にもより高度な利用方法が求められます。そして、サーバに接続する際にも、接続条件が必要になるケースもあります。

 そこで、いくつかのパターンの利用方法を紹介し、新しいHTTP Client APIをどのように利用できるかを紹介します。

接続方法のカスタマイズとBasic認証などへの対応

 前回は、HTTP Clientのオブジェクトを作成する際にはデフォルトの設定で作成するnewHttpClientメソッドを使っていましたが、表1のメソッドを使って接続をカスタマイズすることができます。

表1:HttpClientオブジェクトを作成する際のカスタマイズメソッド
メソッド 概要
authenticator(Authenticator authenticator) 認証方法を設定する。Basic認証など必要な場合に利用する
connectTimeout(Duration duration) 接続タイムアウトを設定する
cookieHandler​(CookieHandler cookieHandler) Cookie処理方法を設定する
executor(Executor executor) 並列実行のためのExecutorクラスを設定する
followRedirects リダイレクトの許可・不許可のポリシーを設定する
priority​(int priority) HTTP2でリクエストする際のデフォルトプライオリティを設定する
proxy(ProxySelector proxySelector) 接続時に利用するプロキシがある場合の設定をする
sslContext​(SSLContext sslContext) SSL/TLS接続時の設定をする
version​(HttpClient.Version version) HTTPのバージョン(1.1もしくは2)を指定する

 リスト1では、Basic認証を使う場合と、開発においてよくある、自己署名証明書を使ったSSL接続の例を示します。

[リスト1]Basic認証と自己証明書を使ったSSL接続に対応するコード例
HttpClient client = HttpClient.newBuilder()
    .authenticator(new BasicAuthenticator("hoge","pswd")) // (1) Basic認証を設定する
    .sslContext(this.createSSLContext())                  // (2) 指定したSSLContextを使う場合
    .build();

//  省略

//  (3) Basic認証を行うクラス
private class BasicAuthenticator extends Authenticator{
    private String username;
    private String password;

    private BasicAuthenticator(String username,String password){
        this.username = username;
        this.password = password;
    }
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username,password.toCharArray());
    }
}

//  (4) 自己署名証明書を受け入れるためのSSLContextの作成
private SSLContext createSSLContext() throws Exception{
    // org.apache.http.ssl.SSLContextBuilderを使っている
    SSLContextBuilder builder = new SSLContextBuilder();
    builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
    return builder.build();
}

 (1)は認証方法の設定をします。認証方法はjava.net.Authenticatorクラスのサブクラスを実装したもの(3)を設定します。

 Basic認証が必要になると、自動的にgetPasswordAuthentication()メソッドがコールされます。つまりパスワードを間違えると再度、パスワードが求められるのでgetPasswordAuthentication()も再度コールされ、最大3回までリトライされます。

 この流れは、UIを伴いパスワードを別で管理している場合には適していますが、例に示すようにあらかじめパスワードがわかっている場合にはリクエスト時にヘッダに設定してしまった方がよいでしょう。

 また、SSLの自己証明書での接続エラーも開発時によく発生する問題です。その場合には、(2)のようにSSLContextのインスタンスを設定し、回避することができます。

 今回のサンプルではSSLContextのインスタンスを(4)のようにApache HttpComponentsのAPIを使って作成しています。

非同期での複数リクエスト

 続いて、複数のリクエストを非同期で処理し、すべての結果が取得可能になり次第それらのデータ処理する場合のコードをリスト2に示します。

[リスト2]非同期で複数リクエストを行う場合のサンプルコード
HttpClient client = HttpClient.newHttpClient();

//  (1) リクエストするメソッドの作成
HttpRequest getRequest1 = HttpRequest.newBuilder().uri(URI.create("http://localhost/req1.php")).build();
HttpRequest getRequest2 = HttpRequest.newBuilder().uri(URI.create("http://localhost/req2.php")).build();

//  (2) 非同期でのリクエストの実行
CompletableFuture<HttpResponse<String>> f1 =
   client.sendAsync(getRequest1,HttpResponse.BodyHandlers.ofString());
CompletableFuture<HttpResponse<String>> f2 =
   client.sendAsync(getRequest2,HttpResponse.BodyHandlers.ofString());

try {
    //  (3) 複数のリクエストを待つ
    CompletableFuture<Void> ff = CompletableFuture.allOf(f1,f2);
    ff.join();

    HttpResponse<String> response1 = f1.get();
    HttpResponse<String> response2 = f2.get();
}
catch(Exception ex){
    //  (4) いずれかのリクエストがエラーになった場合
}

 (1)ではリクエストするためのオブジェクトを作成します。次に、(2)のようにそれらのリクエストを非同期で実行します。

 それぞれのリクエストの結果はCompletableFutureのインスタンスとして取得できるので、(3)のようにallOfメソッドを使えば、すべての結果を待つコードも簡単に記述できます。

 そして、いずれかのリクエストでエラーが発生した場合でも、エラーは(4)のように1カ所で記述でき、エラー処理も非常に簡単です。

次のページ
HTTP Client APIの多様な利用方法(2)

この記事は参考になりましたか?

Java 11の変更点と新しいAPI連載記事一覧
この記事の著者

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/11149 2018/10/31 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー