从/到JSON的hashmap列表转换在Moshi 1.2.0中失败



我想将我的代码从GSon迁移到MOSHI,以便获得ok库的共同底层使用的好处,因为我也在使用OKHTTP和Retrofit。

但是用Gson很简单的任务似乎用MOSHI很复杂:

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

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

简化到最小,我的JSON应该是这样的:

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

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

转换为JSON得到

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

从上面的json字符串反序列化到Class2会得到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());
    }
}

睡了一会儿之后,我找到了一个解决方案(尽管我认为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到JSON的转换按预期工作

最新更新