gson反序列化:嵌套对象的引用所有者

时间:2014-05-18 03:08:03

标签: java json nested deserialization gson

我想为我的Object编写一个自定义反序列化器,但为了实现这一点,我需要访问反序列化对象的另一部分。想象一下像这样的JSON对象:

{
    "id": 2,
    "name": "circle",
    "dependencies": {
        "donut": "e8ed7bbd8715de2f5a85930912fcf238"
    },
    "someReference": {
        "type": "Model",
        "refersTo": "donut"
    }
}

我知道如何编写Adapter / Deserializer。我也知道如何打开" e8ed7bbd8715de2f5a85930912fcf238"通过前者进入Java对象。我不知道和想知道的是如何转动我的"甜甜圈"进入" e8ed7bbd8715de2f5a85930912fcf238"或者最终的Java对象'创建。这些信息位于父母的领域,作为" someReference"对应于另一个Java对象。因此,顶级类是Owner,其字段为:

public class Owner {
    public int id;

    public String name;

    public List<String, Resource> dependencies;

    public MyReference someReference;
}
到目前为止,

idnamedependencies一直都有效。

那么:如何在反序列化过程中引用父对象?这甚至可能吗?什么是我试图做的解决方法?

1 个答案:

答案 0 :(得分:1)

我写了一个解串器来做你想要的(如果我理解的话)。与您提出的问题唯一不同的是,我不知道Reference是什么意思,所以我使用String代替。但我认为您可以轻松调整我的代码。

我的主人定义:

package stackoverflow.questions.q23718183;

import java.util.*;

public class Owner {
    public int id;

    public String name;

    public Map<String, String> dependencies;

    public MyReference someReference;

    @Override
    public String toString() {
        return "Owner [id=" + id + ", name=" + name + ", dependencies=" + dependencies + ", someReference=" + someReference + "]";
    }

    public static class MyReference {
        String type;
        String refersTo;

        @Override
        public String toString() {
            return "MyReference [type=" + type + ", refersTo=" + refersTo + "]";
        }

    }

}

我的解串器:

package stackoverflow.questions.q23718183;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;

import com.google.gson.*;
import com.google.gson.stream.*;
import com.google.gson.reflect.TypeToken;

public class OwnerDeserializer implements JsonDeserializer<Owner> {

    @Override
    public Owner deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (json == null)
            return null;
        else {
            Owner owner = new Owner();
            JsonObject jo = json.getAsJsonObject();

            owner.id = jo.get("id").getAsInt();
            owner.name = jo.get("name").getAsString();

            TypeToken<Map<String, String>> mapType = new TypeToken<Map<String, String>>() {};
            owner.dependencies = context.deserialize(jo.get("dependencies"), mapType.getType());

            Owner.MyReference reference = new Owner.MyReference();
            JsonObject jo2 = jo.get("someReference").getAsJsonObject();
            reference.type = jo2.get("type").getAsString();
            reference.refersTo = owner.dependencies.get(jo2.get("refersTo").getAsString());

            owner.someReference = reference;

            return owner;
        }
    }
}

我的测试代码:

package stackoverflow.questions.q23718183;

import com.google.gson.*;

public class Q23718183 {

    public static void main(String[] args) {
        String s = " {                                                          "+
                "    \"id\": 2,                                                 "+
                "    \"name\": \"circle\",                                      "+
                "    \"dependencies\": {                                        "+
                "        \"donut\": \"e8ed7bbd8715de2f5a85930912fcf238\"        "+
                "    },                                                         "+
                "    \"someReference\": {                                       "+
                "        \"type\": \"Model\",                                   "+
                "        \"refersTo\": \"donut\"                                "+
                "    } "+
                "}";

        GsonBuilder b = new GsonBuilder();
        b.registerTypeAdapter(Owner.class, new OwnerDeserializer());
        Gson g = b.create();

        Owner o = g.fromJson(s, Owner.class);

        System.out.println(o);


    }

}

这就是结果:

Owner [id=2, name=circle, dependencies={donut=e8ed7bbd8715de2f5a85930912fcf238}, someReference=MyReference [type=Model, refersTo=e8ed7bbd8715de2f5a85930912fcf238]]

如您所见,donut被其值替换为dependencies节点。