2016-09-16 9 views
2

OK-Librariesの一般的な使用方法の利点を得るために、GSonからMOSHIにコードを移行したいまた、OKHTTPとRetrofitで。 Gsonと簡単ですMoshi 1.2.0でHashMapsのリストを変換するとエラーが発生する

しかし、タスクはMOSHIを合併しているようだ:

私はオブジェクトのリストを含むクラスを持っています。

これらのオブジェクトは、フィールド名と値のペアで構成されています。これをHashMapとして実装しました。このクラスにはいくつかのコンストラクターとメソッドがありますが、JSONではフィールドと値のペアのみが関連しています。私はMOSHIとバックでJSONに、これらのクラスを変換しようとすると、子供たちが空である

{"children":[{"f1":"v11","f2":"v12"},{"f1":"v21","f2":"v22"}]} 

:最低限まで剥奪

、私のJSONは次のようになります。 JSONへ

変換が

{"children":[{},{}]} 

を与え、上からのClass2にJSON文字列のデシリアライゼーションは、2人の子供を与えるが、子どもたちはempptyあります。

実際のコードでは、その親オブジェクトには他のクラスのオブジェクトのリストも含まれています。これらのクラスは期待どおりに動作します。ここの問題は、私の子クラスがHashMapから拡張されているようです。

Gsonはすべて正常に動作します。

ここではユニットテストですが、動作をテストするために書いてあります。

public class Test_Moshi { 
    private final Moshi moshi = new Moshi.Builder().build(); 


    private static class Class1 extends HashMap<String, Object> { 
     //Some Constructors and methods omitted for the test. 
     //Relevant for the serilisation to JSON are only the keys and values in the map. 
    } 

    private static class Class2 { 
     List<Class1> children = new ArrayList<>(); 
    } 


    @Test public void test1() { 
     Class1 child; 
     Class2 parent = new Class2(); 

     child = new Class1(); 
     child.put("f1", "v11"); 
     child.put("f2", "v12"); 
     parent.children.add(child); 

     child = new Class1(); 
     child.put("f1", "v21"); 
     child.put("f2", "v22"); 
     parent.children.add(child); 

     String json_gson = new Gson().toJson(parent); 
     String json_moshi = moshi.adapter(Class2.class).toJson(parent); 

     assertEquals(json_gson, json_moshi); 
    } 

    @Test public void test2() throws IOException { 
     String json = "{\"children\":[{\"f1\":\"v11\",\"f2\":\"v12\"},{\"f1\":\"v21\",\"f2\":\"v22\"}]}"; 
     Class2 class2 = moshi.adapter(Class2.class).fromJson(json); 

     assertEquals(2, class2.children.size()); 
     assertEquals("Child 1 contains expected number of fields", 2, class2.children.get(0).size()); 
     assertEquals("Child 2 contains expected number of fields", 2, class2.children.get(1).size()); 
    } 
} 

答えて

1

は、いくつかの睡眠後、私は(私はモシは、箱から出して、このケースを処理する必要があることだと思うが)解決策を見つけた:

あなたは答えをここに読むことができるため、モシが正しく地図<を扱います>インタフェース。解決策は、クラスをMap-Interfaceにマップして戻すカスタム・タイプ・アダプターを提供することです。残りはMoshiによって処理されます。

私の質問のコードは、次のように変更する必要があります。 Moshiのドキュメントに記載されているように、Map-Interfaceにマップするアダプタクラスを作成します。

private static class Class1 extends HashMap<String, Object> { 
    public static class class1ToJsonAdapter { 
     @ToJson 
     public Map<String, Object> toJson(Class1 dat) { 
      return (Map<String,Object>)dat; 
     } 

     @FromJson 
     public Class1 fromJson(Map<String,Object> json) { 
      Class1 result = new Class1(); 
      for (String key : json.keySet()) 
       result.put(key, json.get(key)); 
      return result; 
     } 
    } 

    //Some Constructors and methods omitted for the test. 
    //Relevant for the serilisation to JSON are only the keys and values in the map. 
} 

及びこのアダプタは、期待どおり今JSONから及びへの変換が動作

private final Moshi moshi = new Moshi.Builder() 
     .add(new Class1.class1ToJsonAdapter()) 
     .build(); 

モシ・オブジェクトに追加されなければなりません。

関連する問題