简体   繁体   English

使用Gson将单个json条目解析为多个对象

[英]Parsing single json entry to multiple objects with Gson

I have a json response that looks like this: 我有一个json响应,看起来像这样:

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

And I have two classes: Teste and Parameters 我有两个类:Teste和Parameters

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

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

My question is: is there a way to make Gson understand that some of the json attributes should go to the Parameters class, or the only way is to "manually" parse this ? 我的问题是:有没有办法让Gson理解一些json属性应该转到Parameters类,或者唯一的方法是“手动”解析它?

EDIT 编辑

Well, just to make my comment in @MikO's answer more readable: 好吧,只是为了让我在@ MikO的答案中的评论更具可读性:

I'll add a list of an object to the json output, so json response should look like this: 我将向json输出添加一个对象列表,因此json响应应如下所示:

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

And the Deserializer class would look like this: 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;
    }
}

And doing: 并做:

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

Gives me the test object the way I wanted. 以我想要的方式给我测试对象。

The way to make Gson understand it is to write a custom deserializer by creating a TypeAdapter for your Test class. 让Gson理解它的方法是通过为Test类创建一个TypeAdapter来编写自定义反序列化器。 You can find information in Gson's User Guide . 您可以在Gson的用户指南中找到相关信息。 It is not exactly a manual parsing , but it is not that different, since you have to tell Gson how to deal with each JSON value... 它不完全是手动解析 ,但它没有那么不同,因为你必须告诉Gson如何处理每个JSON值...

It should be something like this: 它应该是这样的:

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;
  }
}

Then you have to register the TypeAdapter with: 然后你必须注册TypeAdapter

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

And finally you just have to parse your JSON as usual, with: 最后你必须像往常一样解析你的JSON:

gson.fromJson(yourJsonString, Test.class);

Gson will automatically use your custom deserializer to parse your JSON into your Test class. Gson将自动使用您的自定义反序列化器将您的JSON解析为您的Test类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM