【问题标题】:Conversion of a List of HashMaps from/to JSON fails with Moshi 1.2.0Moshi 1.2.0 从/到 JSON 的 HashMap 列表转换失败
【发布时间】:2017-01-25 05:52:24
【问题描述】:

我想将我的代码从 GSon 迁移到 MOSHI,以便获得 OK-Libraries 的常见底层用法的好处,因为我也在使用 OKHTTP 和 Retrofit。

但是对于 Gson 来说简单的任务,对于 MOSHI 来说似乎很复杂:

我有一个包含对象列表的类。

这些对象由字段名/值对组成——我将其实现为 HashMap。在这个类中还有更多的构造函数和方法,但对于 JSON,只有字段/值对是相关的。

精简到最低限度,我的 JSON 应该如下所示:

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

当我尝试使用 MOSHI 将这些类转换为 JSON 并返回时,孩子是空的。

转换为 JSON 给出

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

从上面到 Class2 的 json-string 反序列化会产生 2 个孩子,但孩子是空的。

在我的真实代码中,父对象还包含其他类的对象列表——这些类按预期工作。这里的问题似乎是我的子类是从 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());
    }
}

【问题讨论】:

    标签: java json moshi


    【解决方案1】:

    睡了一会儿,我找到了一个解决方案(尽管我认为 Moshi 应该开箱即用地处理这种情况):

    正如您在此处阅读的答案,Moshi 正确处理了 Map 接口。解决方案是提供自定义类型适配器,将类映射到 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.
    }
    

    这个适配器必须被添加到moshi-object

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

    现在与 JSON 的转换按预期工作。

    【讨论】:

      猜你喜欢
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 2020-10-31
      • 1970-01-01
      • 2012-08-12
      • 2016-09-16
      • 1970-01-01
      • 2020-01-25
      相关资源
      最近更新 更多