#author("2021-12-14T01:55:51+00:00","","")
#author("2021-12-14T02:32:22+00:00","","")
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。

#contents

以下のような親子モデルで、ネストしたオブジェクトが正しく変換されるか、配列やListやSetなどが正しく変換されるか試してみます。

 public class Parent {
   private String name;
   private int id;
   private Child child;
   public Child getChild() { return child; }
   public void setChild(Child child) { this.child = child;}
   public int getId() { return id;}
   public void setId(int id) { this.id = id;}
   public String getName() { return name;}
   public void setName(String name) { this.name = name;}
   public String toString() {
     return new ToStringBuilder(this).
         append("id", getId()).append("name",
         getName()).append("child", getChild()).toString();
   }
 }

 public class Child {
   private String name;
   public String getName() { return name;}
   public void setName(String name) { this.name = name;}
   public String toString() {
     return new ToStringBuilder(this)
            .append("name", getName()).toString();
   }
 }

***ネストしたオブジェクト [#j4880f41]
 Parent parent = new Parent();
 parent.setId(0);
 parent.setName("親の名前");
 
 Child child = new Child();
 child.setName("子の名前");
 parent.setChild(child);
 
 JSONObject jsonObject = JSONObject.fromObject(parent);
 System.out.println(jsonObject);
 
 Parent p = (Parent) JSONObject.toBean(jsonObject, Parent.class);
 System.out.println(p);
結果
 {"child":{"name":"子の名前"},"name":"親の名前","id":0}
 Parent@6e70c7[id=0,name=親の名前,child=Child@1d63e39[name=子の名前]]

うまくいきました。



***java.util.List [#we6c4678]
java.util.Listを追加しました。
 public class Parent {
   private String name;
   private int id;
 
   private List list; //追加
   public List getList() {return list;} //追加
   public void setList(List list) {this.list = list;} //追加
 
   //private Child child;
   //public Child getChild() { return child; }
   //public void setChild(Child child) { this.child = child;}
   public int getId() { return id;}
   public void setId(int id) { this.id = id;}
   public String getName() { return name;}
   public void setName(String name) { this.name = name;}
   public String toString() {
     return new ToStringBuilder(this).append("id", getId())
                .append("name",getName())
                .append("list", list).toString();
   }
 }
これでやってみると、、

 Parent parent = new Parent();
 parent.setId(0);
 parent.setName("親の名前");
 
 Child child = new Child();
 child.setName("子の名前");
 List<Child> list = new ArrayList<Child>();
 list.add(child);
 parent.setList(list);
 
 JSONObject jsonObject = JSONObject.fromObject(parent);
 System.out.println(jsonObject);
 
 Parent p = (Parent) JSONObject.toBean(jsonObject, Parent.class);
 System.out.println(p);
結果
 {"list":[{"name":"子の名前"}],"name":"親の名前","id":0}
 Parent@12a1e44[id=0,name=親の名前,list=[net.sf.json.util.JSONDynaBean@1ad77a7[
   {name=子の名前}
 ]]]
ChildをListに追加しているのですが、逆変換したオブジェクトはChildではなくnet.sf.json.util.JSONDynaBean になっちゃいました。まあ
 "list":[{"name":"子の名前"}]
とParentクラスだけだと、Listの中身がChildだって情報がないから、当たり前ですね。。


***Listなどのマッピングについて 2009/03/18 追記 [#r3749118]
久しぶりに触ってみたら、モジュールが色々バージョンアップしてるみたいですね。今触ってるのは、2.2.3なのですが、戻り値のクラスがnet.sf.json.util.JSONDynaBean からnet.sf.ezmorph.bean.MorphDynaBeanというのに変更になったりしています。((だからナンなのかはよく分かってないのですが(´д`;) ))

また色々ググってたら、''フィールドの java.util.List をビシっと自分が指定したクラスにマップするようにライブラリに指示できる''ことが分かりました。net.sf.json.JsonConfig クラスというのがあり、これを使うことでJson-libの挙動を色々設定することができます。具体的には以下の通り:

 private JsonConfig createConfig() {
   JsonConfig jsonConfig = new JsonConfig();
   jsonConfig.setRootClass(Parent.class);
   Map<String, Class> classMap = new HashMap<String, Class>();
   classMap.put("list", Child.class);
   jsonConfig.setClassMap(classMap);
   return jsonConfig;
 }
としてJsonConfigインスタンスを作成します。ポイントは
 classMap.put("list", Child.class);
として''フィールドの変数名とそのフィールドにマッピングしたいクラス(List内にaddするクラス)のペアをJsonConfigクラスに設定しておく''ところですね。あとは
 JsonConfig jsonConfig = createConfig();
 Parent p = (Parent) JSONObject.toBean(jsonObject, jsonConfig);
としてJsonConfigをわたしながらtoBeanを実行するだけですね。ちなみにJsonConfigを渡さなかったときは
 Parent p = (Parent) JSONObject.toBean(jsonObject, Parent.class);
として引数にParent.classを指定してましたが、今回Parent.classはJsonConfig経由で渡されてきています。

実行結果は以下の通り:
 Parent@8ab08f[id=0,name=親の名前,list=[Child@a5af9f[name=子の名前]]]

指定通りChildクラスにマップされました!賢いですねー。

ちなみにJsonConfigには[[Javaのフィールド名とJSON内のキー値をマッピング>JSON/Json-libを使う/TIPS集#w051121f]]したり、色々と便利な機能が備わっているようです。

参考
-[[Json-lib に手を出す - 自堕落な投資ずきSEの日記>http://d.hatena.ne.jp/T-miura/20080805/1217935168]]



***java.util.Set [#a5717541]
java.util.Listをjava.util.Setに変えてみました。
 public class Parent {
   private String name;
   private int id;
   private Set children;
   
   public Set getChildren() {return children;}
   public void setChildren(Set children) {this.children = children;}
   public int getId() { return id;}
   public void setId(int id) { this.id = id;}
   public String getName() { return name;}
   public void setName(String name) { this.name = name;}
   public String toString() {
     return new ToStringBuilder(this).append("id", getId())
                .append("name",getName())
                .append("children", children).toString();
   }
 }

これでやってみると、、
 Parent parent = new Parent();
 parent.setId(0);
 parent.setName("親の名前");
 
 Child child = new Child();
 child.setName("子の名前");
 Set<Child> children = new HashSet<Child>();
 children.add(child);
 parent.setChildren(children);
 
 JSONObject jsonObject = JSONObject.fromObject(parent);
 System.out.println(jsonObject);
 
 Parent p = (Parent) JSONObject.toBean(jsonObject, Parent.class);
 System.out.println(p);
結果
 2006/12/31 18:01:40 org.apache.commons.beanutils.PropertyUtilsBean invokeMethod
 致命的: Method invocation failed.
 java.lang.IllegalArgumentException: argument type mismatch
BeanUtilsが例外になっちゃいました。


***Setのマッピングについて 2009/03/18 追記 [#sd2894e3]
先の例と同じでJsonConfigで
 Map<String, Class> classMap = new HashMap<String, Class>();
 classMap.put("children", Child.class);
 jsonConfig.setClassMap(classMap);
とすることで、実行すると
 Parent@4d921a[id=0,name=親の名前,children=[Child@4c6320[name=子の名前]]]
正しく動くことが確認できました。上の例外の件はとりあえず忘れちゃいましょう:-)。




***配列 [#m3694282]
配列も同じですね。ダメですねぇ。

:2009/03/18追記|配列も正しく動きます。実際実行してみると、
 Parent@8ab08f[id=0,name=親の名前,children={Child@a5af9f[name=子の名前]}]
となりOKそうですね。


***java.util.Map [#ge97d174]
java.util.Setをjava.util.Mapに変えてみました。
 public class Parent {
   private String name;
   private int id;
   private Map children;
   
   public Map getChildren() {return children;}
   public void setChildren(Map children) {this.children = children;}
   public int getId() { return id;}
   public void setId(int id) { this.id = id;}
   public String getName() { return name;}
   public void setName(String name) { this.name = name;}
   public String toString() {
     return new ToStringBuilder(this).append("id", getId())
                .append("name",getName())
                .append("children", children).toString();
   }
 }

これでやってみると、、
 Parent parent = new Parent();
 parent.setId(0);
 parent.setName("親の名前");
 
 Child child = new Child();
 child.setName("子の名前");
 Map children = new HashMap();
 children.put("child1", child);
 parent.setChildren(children);
 
 JSONObject jsonObject = JSONObject.fromObject(parent);
 System.out.println(jsonObject);
 
 Parent p = (Parent) JSONObject.toBean(jsonObject, Parent.class);
 System.out.println(p);
結果
 {"name":"親の名前","id":0,"children":{"child1":{"name":"子の名前"}}}
 Parent@b1b4c3[id=0,name=親の名前,children={child1=net.sf.json.util.JSONDynaBean@1efb836[
   {name=子の名前}
 ]}]
例によってkey=child1とともに代入されたChildはnet.sf.json.util.JSONDynaBeanになっちゃいましたが、一応正常終了ですね。



***Mapのマッピングについて 2009/03/18 追記 [#na202aec]
先のJsonConfigクラスを使用することでうまくマッピングすることができそうです。
 private static JsonConfig createConfig() {
   JsonConfig jsonConfig = new JsonConfig();
   jsonConfig.setRootClass(Parent.class);
   Map<String, Class> classMap = new HashMap<String, Class>();
   classMap.put("child1", Child.class);
   jsonConfig.setClassMap(classMap);
   return jsonConfig;
 }
このように、child1に対してChildクラスですよって指定をすることで、
 Parent@672bbb[id=0,name=親の名前,children={child1=Child@dd75a4[name=子の名前]}]
となりました。。Mapのキーが増えていっても、
   classMap.put("child1", Child.class);
   classMap.put("child2", Child.class);
のようにそれぞれにマップするクラスを指定すれば良いみたいです。

**関連リンク [#r563fb35]
-[[Javaのフィールド名とJSON内のキー値をマッピング>JSON/Json-libを使う/TIPS集#w051121f]]

----
この記事は
#vote(おもしろかった[12],そうでもない[1])
#vote(おもしろかった[13],そうでもない[1])
-やり方が悪いような気がするなあ。。でも時間切れ。。。 -- [[きの]] &new{2006-12-31 23:10:37 (日)};
- Enumは? -- [[とおりすがり]] &new{2007-03-09 (金) 09:16:17};

#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS