【问题标题】:Parsing single json entry to multiple objects with Gson使用 Gson 将单个 json 条目解析为多个对象
【发布时间】:2013-07-16 14:59:12
【问题描述】:

我有一个如下所示的 json 响应:

{
    "id":"001",
    "name":"Name",
    "param_distance":"10",
    "param_sampling":"2"
}

我有两个类:Teste 和 Parameters

public class Test {
    private int id;
    private String name;
    private Parameters params;
}

public class Parameters {
    private double distance;
    private int sampling;
}

我的问题是:有没有办法让 Gson 明白某些 json 属性应该转到 Parameters 类,或者唯一的方法是“手动”解析这个?

编辑

好吧,只是为了让我在@MikO 的回答中的评论更具可读性:

我将在 json 输出中添加一个对象列表,因此 json 响应应如下所示:

  {
    "id":"001",
    "name":"Name",
    "param_distance":"10",
    "param_sampling":"2",
    "events":[
        {
            "id":"01",
            "value":"22.5"
        },
        {
            "id":"02",
            "value":"31.0"
        }
    ]
}

Deserializer 类看起来像这样:

public class TestDeserializer implements JsonDeserializer<Test> {
    @Override
    public Test deserialize(JsonElement json, Type type,
            JsonDeserializationContext context) throws JsonParseException {

        JsonObject obj = json.getAsJsonObject();

        Test test = new Test();
        test.setId(obj.get("id").getAsInt());
        test.setName(obj.get("name").getAsString());        

        Parameters params = new Parameters();
        params.setDistance(obj.get("param_distance").getAsDouble());
        params.setSampling(obj.get("param_sampling").getAsInt());
        test.setParameters(params);

        Gson eventGson = new Gson();
        Type eventsType = new TypeToken<List<Event>>(){}.getType();
        List<Event> eventList = eventGson.fromJson(obj.get("events"), eventsType);
        test.setEvents(eventList);
        return test;
    }
}

然后做:

GsonBuilder gBuilder = new GsonBuilder();
gBuilder.registerTypeAdapter(Test.class, new TestDeserializer());
Gson gson = gBuilder.create();
Test test = gson.fromJson(reader, Test.class);

按照我想要的方式给我测试对象。

【问题讨论】:

    标签: java json parsing gson


    【解决方案1】:

    让 Gson 理解它的方法是通过为您的 Test 类创建 TypeAdapter 来编写自定义反序列化器。您可以在Gson's User Guide 中找到信息。这并不完全是手动解析,但也没有那么不同,因为你必须告诉 Gson 如何处理每个 JSON 值...

    应该是这样的:

    private class TestDeserializer implements JsonDeserializer<Test> {
      public Test deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
          throws JsonParseException {
    
        JsonObject obj = json.getAsJsonObject();
    
        int id = obj.get("id").getAsInt();
        String name = obj.get("name").getAsString();
    
        double distance = obj.get("param_distance").getAsDouble();
        int sampling = obj.get("param_sampling").getAsInt();
    
        //assuming you have suitable constructors...
        Test test = new Test(id, name, new Parameters(distance, sampling));
    
        return test;
      }
    }
    

    然后你必须注册TypeAdapter

    GsonBuilder gson = new GsonBuilder();
    gson.registerTypeAdapter(Test.class, new TestDeserializer());
    

    最后你只需要像往常一样解析你的 JSON,使用:

    gson.fromJson(yourJsonString, Test.class);
    

    Gson 将自动使用您的自定义反序列化器将您的 JSON 解析为您的 Test 类。

    【讨论】:

    • 是的。在我曾经玩过的一些代码中,我有很多“示例”。这是一个类,但该目录中的大多数内容都有一个自定义适配器:github.com/chriskessel/MyHex/blob/master/src/kessel/hex/domain/…
    • 好的。那行得通。但是让我们把这个问题复杂化一点。我在这个测试类中也有一个列表。列表。我将如何在此方法中包含此列表解析。根据我的阅读,我必须使用 JsonArray 类,对吗?
    • 好的。我也得到了事件列表。您可以获取元素并使用常规 Gson 对象对其进行解析。 Gson eventGson = new Gson(); Type eventsType = new TypeToken&lt;List&lt;Event&gt;&gt;(){}.getType(); List&lt;Event&gt; eventList = eventGson.fromJson(obj.get("events"), eventsType); test.setEvents(eventList); Json 输入类似于:{"id":"001","name":"Name","param_distance":"10","param_sampling":"2", "events":[{"id":"01"}, {"id":"02"}]}
    • 我已经用这个信息更新了我的问题。感谢您的帮助... =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多