2010年6月22日火曜日

JSONICの使い方

最近は、JSON形式のデータを熱かったアプリを作ろうと考えているので、
JSONICについて調べてみました。

JSONICっていうのは簡単にいうと、JavaでJSON形式のデータを扱うためのライブラリです。
ダウンロードはこちらから↓
JSONIC

使い方はいたって簡単。

// JSONICをインポート
import net.arnx.jsonic.JSON;

public class JsonicSample {
    public static void main(String[] args) {

        final JsonicSample jsonicSample = new JsonicSample();
        jsonicSample.go();

    public void go() {
        // エンコード(Java → JSON)対象のクラス
        final Hoge hoge = new Hoge();
        hoge.setName("sample");
        hoge.setAge(10);

        // JSON形式にエンコード
        final String hogeJson = JSON.encode(hoge);

        // {"name":"sample","age":10} が出力されます
        System.out.println("エンコード結果:" + hogeJson);


        final String hogeJson2 = "{\"name\":\"sample2\",\"age\":20}";

        // JSON形式のデータをJavaのclassに変換(デコード)
        final Hoge hoge2 = JSON.decode(hogeJson2, Hoge.class);
        System.out.println("hoge2.name:" + hoge2.getName());
        System.out.println("hoge2.age:" + hoge2.getAge());

        // 配列を含むJSON形式のデータを用意
        final String hoges = "{\"id\":\"10\",\"hoges\":[{\"name\":\"test\",\"age\":1},{\"name\":\"sample2\",\"age\":2}]}";

        final HogeList hogeList = JSON.decode(hoges, HogeList.class);

        // hogesのようにHogeの形式の配列を持つJSONを、HogeクラスのListをもつクラスにデコードすることが出来ます
        System.out.println("hogeList.id:" + hogeList.getId());
        for (final Hoge tmp : hogeList.getHoges()) {
            System.out.println("tmp.name:" + tmp.getName());
            System.out.println("tmp.age:" + tmp.getAge());
        }
    }

    /**
     * JSONに対応するクラス
     * 各フィールド名をJSONのKEY名と同じにする
     * JSONのKEY名が 「sample-name」のような場合は「sampleName」とする
     */
    class Hoge {

        private String name;

        private int age;

        public void setName(final String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setAge(final int age) {
            this.age = age;
        }

        public int getAge() {
            return age;
        }
    }

    /**
     * HogeクラスのListを保持するクラス
     */
    class HogeList {

        private String id;

        private List<Hoge> hoges;

        public void setId(final String id) {
            this.id = id;
        }

        public String getId() {
            return id;
        }

        public void setHoges(final List<Hoge> hoges) {
            this.hoges = hoges;
        }

        public List<Hoge> getHoges() {
            return hoges;
        }
    }
}

こんな感じです。フィールドの型の自動変換についてはかなり柔軟に対応してくれるみたいです。
詳しくは、JSONICのページを見てください;

2010年6月17日木曜日

Java7 使ってみました。(TransferQueue)

今度リリースされる、Java7の新クラスの1つである「TransferQueue」を使ってみました。
説明によると、TransferQueueはQueueのクラスで、あるスレッドがこのQueueにオブジェクトを
追加すると、別のスレッドがQueue内の先程追加されたオブジェクトを削除しないと
オブジェクトを追加したスレッドに制御が戻らない。とのこと。
言葉で説明しても、うまく伝わらないので、早速使ってみます。

その前に、まずはJava7のダウンロードから。
ダウンロードはこちらから↓

早速、Eclipseの設定画面でJava7を指定してみたけど、コンパイラー準拠レベルには1.6までしか
現れない・・・。まだ、正式リリース版だからでは無いからでしょうか?
仕方ないので、基本設定は1.6のままで勧めます。

Javaプロジェクトを作成して、ビルドパスから
「JREシステム・ライブラリー」をjre7に変更してやります。
これで、先程ダウンロードしたJava7が使えるようになります。

下がサンプルソース。
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;

public class TransferQueueSample {

 private TransferQueue queue;

 public static void main(String[] args) {

   final TransferQueueSample sample = new TransferQueueSample();

   sample.go();
 }

 protected void go() {

  queue = new LinkedTransferQueue();

  final Thread threadA = new Thread(new ActionA());
  final Thread threadB = new Thread(new ActionB());

  threadA.start();
  threadB.start();
 }

 class ActionA implements Runnable {

  public void run() {
   try {
    System.out.println("ActionA:testを追加します。");
    queue.transfer("test");
    System.out.println("ActionA:testを追加しました。");
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

 class ActionB implements Runnable {

  public void run() {
   try {
    System.out.println("ActionB:5s間待機します。");
    int i = 0;
    while (i++ &lt; 5) {
     Thread.sleep(1000);
     System.out.println(i);
    }
    queue.remove();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

}

簡単に説明すると、まずActionAは、TransferQueueに文字列"test"を 追加します。この際に使用するメソッドはtransfer(Object)。 このtransferメソッドが、queneにオブジェクトを追加し、そのオブジェクトが 削除されるまで、制御をActionAに返さないようにしています。 transferが実行された後は、メッセージを表示します。 次に、ActionBです。ActionBは5s停止後、quene内のオブジェクトを削除します。 実行してみるとわかると思いますが、ActionAがtransferメソッドを呼び出した後に、 ActionBのカウントダウンが表示された後に、ActionA側の"testを追加しました"との メッセージが表示されたと思います。 Java6まででは、このような動きを実現するには、while()でquenu内の監視をしなくては いけませんでしたが、transferメソッドを使用することで簡単に実現できるようになっています。