2009-05-14
JSON (json-lib) で嵌ったこと
今日も少し書きます。
- 配列は全て List になる?
.NET から バイナリデータ(byte[])を JSON 文字列化して Java 側で byte[] のフィールドに変換しようとしたらエラーになった。
(JSON 文字列は、 "content" : [1,0,0,133,〜] こんな感じ)
結局 フィールドを List<Integer> にしたら、問題無く取り込めた。JsonConfig で吸収出来るのかな?
※Java で List<Byte> を byte[] に簡単に変換する方法ってあるの?
Java のメソッドでプリミティブ型を引数に取るものは、そのラッパー型でも渡せる様にオーバーロードしてくれてたらいいのに。。
※2009/06/05 追記:何か byte[] でも受け取れるケースがあるみたい。なんでだろう?
Java 側での話し。getter として使おうと思ったわけではないのに…。これも JsonConfig の設定次第で逃げれると思う。
プロパティを言語仕様化したらいいのに。
※そういや、boolean の getter は is〜になるんだっけ? boolean 型は試してないな、明日試してみよう。
- List がネストしてても大丈夫
言葉で説明するのが大変なので、コードで書きます。
setter、getter は省略。
public class Org { private List<User> users; } public class User { private List<Item> items; } public class Item { private List<Integer> content; }
な Org クラスのインスタンスも JSON 文字列 の相互変換可能でした。
.NET (System.Runtime.Serialization.Json.DataContractJsonSerializer) は、変わったことをせずとも JSON 文字列からインスタンスの生成が可能。
Java (json-lib)は、JsonConfig の設定が必要。
JsonConfig config = new JsonConfig(); config.setRootClass(Org.class); Map<String, Class> classMap = new HashMap<String, Class>(); classMap.put("users", User.class); classMap.put("items", Item.class); config.setClassMap(classMap);
Org(ルートにあたる)クラスのフィールドでなくても、JsonConfig の classMap に指定すればちゃんと解釈してくれた。
ただ、フィールド名が被る場合は多分ダメなんじゃないかなと思って未検証。
フィールド名が被るケース(Org クラスと User クラスに detail という同名のフィールドが存在する)
public class Org { private List<User> detail; } public class User { private List<Item> detail; } public class Item { private List<Integer> content; }

def list = new ArrayList<Byte>();
を
list as bytes[]
で変換できますね。
この機能javaにもほしい。
Groovy 便利ですよね〜。
今、仕事でも Groovy を使ってよいか探りを入れ中です!