使用Gson在Java中反序列化任意JSON并尊重整数

时间:2018-12-07 17:40:04

标签: java json gson

我有一些JSON字符串片段,看起来像这样:

{label: "My Label"}

{maxlength: 5}

{contact: {name: "John", "age": 5, children: [{"name": "Mary"]}}

等,即它可以是具有任何键名或值类型的任何 JSON对象。

现在,我正在反序列化执行类似以下的简单操作:

final Gson gson = new Gson();
Object newValue = gson.fromJson(stringValue, Object.class);

这适用于99%的用例。但是as is mentioned here,它将所有整数转换为双精度。

我可以按照其他地方的建议注册类型适配器。所以我写了以下内容:

final Gson gson = new GsonBuilder()
                        .registerTypeAdapter(Object.class, new DoubleToInt())
                        .create();
Object newValue = gson.fromJson(stringValue, Object.class);

private static class DoubleToInt implements JsonDeserializer<Object>{

    @Override  
    public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

        // do my custom stuff here

        return json;
    }
}

但这根本不起作用。这就像类型适配器甚至都没有注册,因为断点从未在deserialize方法中命中过。

2 个答案:

答案 0 :(得分:1)

在您链接的帖子中,他们建议使用自定义类,以告诉您应该使用什么数据类型,而不是使用Object.class。您是否尝试过这样做?

    class CustomClass{
      String label;
      int maxLength;
      ...
    }

    Object newValue = gson.fromJson(stringValue, CustomClass.class);

答案 1 :(得分:1)

正如您所链接的文章所建议的那样,您应该创建自定义类,所以我做到了,它可以正常工作:

public class Test {
    public static void main(String[] args) {
        final Gson gson = new GsonBuilder()
            .registerTypeAdapter(MyClass.class, new DoubleToInt())
            .create();
        String stringValue = "{contact: {name: \"John\", \"age\": 5, children: [{\"name\": \"Mary\"}]}}";

        MyClass newValue = gson.fromJson(stringValue, MyClass.class);
        System.out.println(newValue.toString());
    }

    private static class DoubleToInt implements JsonDeserializer<MyClass> {

        @Override
        public MyClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

            // do my custom stuff here

            return new MyClass(json);
        }
    }
}

class MyClass {
    private JsonElement element;

    MyClass(JsonElement element) {
        this.element = element;
    }

    @Override
    public String toString() {
        return element.toString();
    }
}