2016-09-16 169 views
2

我想將我的代碼從GSon遷移到MOSHI,以便獲得OK庫的常見底層用法的好處,因爲我正在使用此工具還有OKHTTP和Retrofit。將HashMap的列表從/轉換爲JSON失敗,使用Moshi 1.2.0

但是,這是GSON簡單的任務似乎與MOSHI複雜:

我有一個包含對象列表的類。

而這些對象由字段名/值對組成 - 我將它實現爲一個HashMap。在這個類中還有一些構造函數和方法,但對於JSON只有字段/值對是相關的。

精簡到最低限度,我的JSON應該是這樣的:

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

當我嘗試這些類轉換成JSON與MOSHI和背部,孩子們都是空的。

轉換爲JSON給

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

而且JSON字符串從上面的Class2的deserialisation給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接口並返回。其餘的則由Moshi負責處理。

我的問題中的代碼必須更改如下: 按照Moshi文檔中的描述創建映射到Map接口的適配器類。

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. 
} 

與此適配器已被添加到魔石對象

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

現在可以按預期的轉換,從和JSON。