当前位置: 首页 > 面试题库 >

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

舒阳州
2023-03-14
问题内容

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

JSON字串:

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

我有这两个课程:

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

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

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

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


问题答案:

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

首先,您需要包括一个新的类,而不是已有的两个类:

public class Response {
    public VkAudioAlbumsResponse response;
}

然后,您需要一个自定义解串器,类似于以下内容:

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

然后,您必须像这样反序列化JSON:

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

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

然后,它意识到此属性是类型的VkAudioAlbumsResponse,因此它将使用您创建的自定义反序列化器对其进行解析,该反序列化器将处理JSON响应的其余部分并返回对象VkAudioAlbumsResponse

注意:反序列化器中的代码非常简单,因此我想您将毫无疑问地了解它…有关更多信息,请参见 Gson API
Javadoc



 类似资料:
  • 我有一个JestClient(elasticsearch)响应,我试图将其反序列化为一个对象。该对象包含两个DateTime字段,而在响应中,它们是字符串,因此我得到: 所以,我创建了一个自定义反序列化器来解决这个问题…然而,无论我做什么,我总是得到同样的错误。不知何故它没有注册使用它? 最后,我试图解析JestClient响应的代码: 无论我尝试什么,我总是得到上面的错误,我甚至不确定在这一点上

  • 问题内容: 确定,所以我编辑了问题,因为它不够清楚。 编辑2 :更新了JSON文件。 我在Android应用程序中使用GSON,我需要解析来自服务器的JSON文件,这些文件有点太复杂了。我不想让我的对象结构太沉重,所以我想简化内容: 所以我的对象的结构将不是JSON文件的结构。 例如,如果在JSON中,我有以下内容: 我不想保留我当前的对象结构,即一个对象,其中包含一个和一个“总计”。但是我只想将

  • 问题内容: 我正在使用Flickr API 。调用该方法时,默认的JSON结果为: 我想将此响应解析为Java对象: JSON属性应按以下方式映射: 不幸的是,我无法找到一种使用Annotations做到这一点的好方法。到目前为止,我的方法是将JSON字符串读入a 并从中获取值。 但是我认为,这是有史以来最不优雅的方式。有没有简单的方法,可以使用注释还是自定义反序列化器? 这对我来说将是很明显的,

  • 我试图用Jackson库创建复杂类的对象。每个对象都有一个模式,反序列化器需要使用该模式来解释JSON。我的问题是如何向反序列化器提供模式? 反序列化程序扩展了类JSONDeserializer,该类具有无参数构造函数和必须重写的抽象方法反序列化(解析器、上下文)。我想改用另一种方法反序列化(解析器、上下文、值),其中值是部分构造的对象,其中包括模式。也就是说,反序列化方法可以调用value。sc

  • 问题内容: 我在反序列化以下json数组时遇到麻烦(对不起,大小): 如果将其粘贴到json-viewer中,则会得到以下结构: 现在,包含具有坐标的数组的数组具有可变大小。所以我想在Java中,整个对象应该是一个数组,其中包含数组的集合,每个数组都包含一个。就像是 但是gson不接受这一点。我收到以下错误消息: 这似乎很奇怪,因为对我来说好像不像一个数组。但这可能使我感到困惑,或多或少地迷路了…

  • 我有一个REST Api服务,它给了我以下响应 实际上,我希望json的格式如下所示(应为json) 为了实现这一点,我编写了以下代码 在上面的代码中,我以字符串的形式从REST Api获取响应,并将其放入变量中。此外,我将其反序列化为映射 进一步,我迭代它并形成我的预期Json响应。 我的问题是:在这种方法中,为了获得预期的json,我需要再次迭代反序列化的json,并手动形成它。 在反序列化自