// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。

#contents


**JSONの変数名とJavaフィールド名が異なる場合にマッピングを指定する [#w051121f]
[[JSON/Json-libを使う/JSONからJavaへいろんな変換]] のページで、Json-libを用いてJSONオブジェクトやJSON文字列からJavaオブジェクトを生成してみました。

その際に、JsonConfigクラスを用いてJavaクラスのフィールドにあるListやSet、またMapなどのオブジェクトに[[どんなクラスをマッピングさせるか>JSON/Json-libを使う/JSONからJavaへいろんな変換#r3749118]]などを指定できることを書きました。

さて、このJsonConfigクラスですが、Json-libの様々な挙動を設定することができます。その前に、そもそもJson-libはデフォルトではJSON内のキー値をJavaの同じ名前のフィールド名に自動でマッピングするようにできています。具体的には
 {"children":[{"name":"子の名前"},{"name":"子の名前2"}],"id":0,"name":"親の名前"} 
に対して、idやnameはJavaクラスのフィールドのidやnameという変数にマッピングします。逆にいうとキー値と変数名が異なる場合は当たり前ですが空振りしてしまうわけですね。そんなときにはJsonConfig で設定を変更することによって、JSON内の値を任意の変数にマッピングすることができます。

試しに
 {"children":[{"name":"子の名前2"}],"id":0,"name_json":"親の名前"} 
を
 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();
   }
 }
へマッピングしてみます。JSON文字列内のname_jsonというキー値を、Javaクラスのnameフィールドにマッピングします。

まずは普通にJson-libを使用すると、
 public static void main(String[] args) {
   // {"children":[{"name":"子の名前2"}],"id":0,"name_json":"親の名前"}
   // からJSONObjectを作成します
   String json = "{\"children\":[{\"name\":\"子の名前2\"}],\"id\":0,\"name_json\":\"親の名前\"} ";
   System.out.println(json);
   JSONObject jsonObject = JSONObject.fromObject(json);
   System.out.println(jsonObject);
   JsonConfig jsonConfig = createConfig();
   Parent p = (Parent) JSONObject.toBean(jsonObject, jsonConfig);
   System.out.println(p);
 }
 
 private static JsonConfig createConfig() {
   JsonConfig jsonConfig = new JsonConfig();
   jsonConfig.setRootClass(Parent.class);
   Map<String, Class> classMap = new HashMap<String, Class>();
   classMap.put("children", Child.class);
   jsonConfig.setClassMap(classMap);
   return jsonConfig;
 }
実行結果は以下の通り。
 {"children":[{"name":"子の名前2"}],"id":0,"name_json":"親の名前"}
 Parent@ed32c4[id=0,name=<null>,children=[Child@719f1f[name=子の名前2]]]
当たり前ですがParentクラスのnameフィールドはマッピングが空振りしてnullになっています。

ではJsonConfigに設定を追加してみます。やり方は、JSONの変数名に対してJavaフィールド名を返すメソッドを持ったクラス JavaIdentifierTransformer を定義して設定してあげるだけですね。

実際にやってみます。createConfig() の中身を以下のように書き換えます。
 private static JsonConfig createConfig() {
   JsonConfig jsonConfig = new JsonConfig();
   jsonConfig.setRootClass(Parent.class);
   Map<String, Class> classMap = new HashMap<String, Class>();
   classMap.put("children", Child.class);
   jsonConfig.setClassMap(classMap);
   jsonConfig
     .setJavaIdentifierTransformer(new JavaIdentifierTransformer() {
     @Override
     public String transformToJavaIdentifier(String param) {
       if (param != null) {
         if ("name_json".equals(param)) { //jsonのname_jsonはParentクラスのnameにマッピング
           return "name";
         }
       }
       return param;
     }
   });
   return jsonConfig;
 }
このようにマッピングを指示するクラスを定義し、JsonConfigに設定してやればOKです。実行結果は以下の通り。
 {"children":[{"name":"子の名前2"}],"id":0,"name_json":"親の名前"}
 Parent@caf0ed[id=0,name=親の名前,children=[Child@719f1f[name=子の名前2]]]
nameフィールドに想定通り値が設定されました。


***関連リンク [#ea61ac52]
-[[JSON/Json-libを使う/JSONからJavaへいろんな変換]] 
-[[Listなどの中のオブジェクトの型を指定する>JSON/Json-libを使う/JSONからJavaへいろんな変換#r3749118]]

----
この記事は
#vote(おもしろかった[1],そうでもない[0])
#vote(おもしろかった[2],そうでもない[0])

#comment
#topicpath


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


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS