第28夜 Javaの高機能非同期HTTPクライアント その2

http://d.hatena.ne.jp/shin/20101223/p1 の続き

前回はFutureを利用した。個人的にはJavaの場合こちらのほうが自由度が高くて好きだが、お手軽にコールバックをさせたいという場合もあるだろう。

というわけで、今回はコールバック版。RESTのリクエスト結果が戻されたときに呼び出されます。

import com.sun.jersey.api.client.AsyncWebResource;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.async.TypeListener;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Async2 {

    public static void main(String[] args) throws Exception {
        Client client = Client.create();

        AsyncWebResource awr1 = client.asyncResource("https://sites.google.com/site/shin68k/");
        AsyncWebResource awr2 = client.asyncResource("https://sites.google.com/site/shin68k/product/purewind");

        awr1.get(new TypeListener<String>(String.class) {
            public void onComplete(Future<String> future) throws InterruptedException {
                try {
                    System.out.println("awr1:"+future.get());
                } catch (ExecutionException ex) {
                    Logger.getLogger(Async2.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
        });
        awr2.get(new TypeListener<String>(String.class) {
            public void onComplete(Future<String> future) throws InterruptedException {
                try {
                    System.out.println("awr2:"+future.get());
                } catch (ExecutionException ex) {
                    Logger.getLogger(Async2.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

        client.getExecutorService().shutdown();

    }

}

簡単ですね。Javascriptになれている人はこちらがいいのでしょうが、スレッドを意識するプログラムの場合どのスレッドで実行されているかなどはちゃんと認識しておきましょう。スレッドの作成方法を上記ではデフォルト利用(複数スレッドのプールをしている)ですが、場合によってはシングルスレッドにするとかもありかもしれません。また、GUI操作の場合もスレッドを意識しましょう。


awr1.get(TypeListener)部分ですが、このメソッドの戻り値はFutureでもあります。したがってコールバックで実行しつつ、その後完了しているかどうかのチェックやキャンセル、値の取得などが可能になります。

Future<String> future1 = awr1.get(new TypeListener<String>(String.class) {
〜
future1.cancel(true);//メインスレッドからキャンセル実行

非同期で通信を行いたいという場合はかなり多いと思います。むしろその後の操作がブロックされてはいけませんから非同期こそ推奨だと思われます。そんなときに今回や前回の非同期APIは役に立つはずです。


以上5回にわたってJavaによるHTTPクライアントAPIの使い方を軽く紹介してきましたが、JAX-RS 2.0ではこのクライアントAPIが標準化される見込みです。より手軽に、簡単になることでしょう。