Java 使用 Gson 的自定义 JSON 反序列化器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16590377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 12:20:07  来源:igfitidea点击:

Custom JSON deserializer using Gson

javajsonparsinggson

提问by nikita.zhelonkin

I have a problem with parsing a JSON response using Gson.

我在使用 Gson 解析 JSON 响应时遇到问题。

JSON string:

JSON 字符串:

response: [
  2, {
    owner_id: 23972237,
    album_id: 25487692,
    title: 'album not new'
  }, {
    owner_id: 23972237,
    album_id: 25486631,
    title: 'фыв'
  }
]

I have these 2 classes:

我有这两个类:

public class VkAudioAlbumsResponse {
    public ArrayList<VkAudioAlbum> response;
    public VkError error;
}

public class VkAudioAlbum {
    public int owner_id;
    public int album_id;
    public String title;
}

But I have an Exception when parse this using Gson. I know this is because response array first element is not an object, but integer.

但是在使用 Gson 解析这个时我有一个异常。我知道这是因为响应数组的第一个元素不是对象,而是整数。

So the question is, can I solve it somehow?

所以问题是,我能以某种方式解决它吗?

采纳答案by MikO

You have to write a custom deserializer. I'd do something like this:

您必须编写自定义反序列化器。我会做这样的事情:

First you need to include a new class, further than the 2 you already have:

首先,您需要包含一个新类,比您已有的 2 个类更进一步:

public class Response {
    public VkAudioAlbumsResponse response;
}

And then you need a custom deserializer, something similar to this:

然后你需要一个自定义的解串器,类似于这个:

private class VkAudioAlbumsResponseDeserializer 
    implements JsonDeserializer<VkAudioAlbumsResponse> {

  @Override
  public VkAudioAlbumsResponse deserialize(JsonElement json, Type type,
        JsonDeserializationContext context) throws JsonParseException {

    JsonArray jArray = (JsonArray) json;

    int firstInteger = jArray.get(0); //ignore the 1st int

    VkAudioAlbumsResponse vkAudioAlbumsResponse = new VkAudioAlbumsResponse();

    for (int i=1; i<jArray.size(); i++) {
      JsonObject jObject = (JsonObject) jArray.get(i);
      //assuming you have the suitable constructor...
      VkAudioAlbum album = new VkAudioAlbum(jObject.get("owner_id").getAsInt(), 
                                            jObject.get("album_id").getAsInt(), 
                                            jObject.get("title").getAsString());
      vkAudioAlbumsResponse.getResponse().add(album);
    }

    return vkAudioAlbumsResponse;
  }  
}

Then you have to deserialize your JSON like:

然后你必须反序列化你的 JSON,如:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(VkAudioAlbumsResponse.class, new VkAudioAlbumsResponseDeserializer());
Gson gson = gsonBuilder.create();
Response response = gson.fromJson(jsonString, Response.class);

With this approach, when Gson tries to deserialize the JSON into Responseclass, it finds that there is an attribute responsein that class that matches the name in the JSON response, so it continues parsing.

使用这种方法,当 Gson 尝试将 JSON 反序列化为Response类时,它发现该类中有一个response与 JSON 响应中的名称匹配的属性,因此它继续解析。

Then it realises that this attribute is of type VkAudioAlbumsResponse, so it uses the custom deserializer you have created to parse it, which process the remaining portion of the JSON response and returns an object of VkAudioAlbumsResponse.

然后它意识到这个属性的类型是VkAudioAlbumsResponse,所以它使用你创建的自定义反序列化器来解析它,它处理 JSON 响应的剩余部分并返回一个对象VkAudioAlbumsResponse

Note: The code into the deserializer is quite straightforward, so I guess you'll have no problem to understand it... For further info see Gson API Javadoc

注意:解串器中的代码非常简单,所以我想你理解它应该没有问题......有关更多信息,请参阅Gson API Javadoc