Gson 和反序列化包含数组的对象数组

2022-08-31 13:38:17

我正在尝试使用Gson反序列化从我的Web服务返回的json字符串

该结构将作为 返回。TypeDTO[]

哪里是像TypeDTO

int id;
String name;
ArrayList<ItemDTO> items[] 

和 ItemDTO 就像

int id;
String name;
Boolean valid;

当我调用代码时,如下所示

Gson gson = new Gson();
TypeDTO[] mytypes = (TypeDTO[]) gson.fromJson(reply, TypeDTO[].class);

对象内的所有内容都为空

但是,如果我使用

JSONArray并且要从 org.json jar 中逐个提取它们,它可以正常工作,并且相应地填充字段。JSONObject

关于我做错了什么的任何想法?Gson的速度非常快吗?还是我最好坚持我已经工作的东西?

谢谢,大卫


答案 1

原始问题中的示例 Java 数据结构与注释中 JSON 结构的描述不匹配。

JSON 被描述为

“一个 {object 的数组,其中一个数组为 {object}}”。

就问题中描述的类型而言,JSON转换为Java数据结构,该结构将与JSON结构相匹配,以便于与Gson进行反序列化

“一个 {TypeDTO 对象的数组,其数组为 {ItemDTO object}}”。

但是问题中提供的Java数据结构不是这样的。相反,它是

“一个 {TypeDTO 对象的数组,其数组包含一个数组的 {ItemDTO object}}”。

二维数组 != 一维数组。

第一个示例演示如何使用 Gson 简单地反序列化和序列化 JSON 结构,该结构是“具有 {object}} 数组的 {object}} 的数组”。

input.json Contents:

[
  {
    "id":1,
    "name":"name1",
    "items":
    [
      {"id":2,"name":"name2","valid":true},
      {"id":3,"name":"name3","valid":false},
      {"id":4,"name":"name4","valid":true}
    ]
  },
  {
    "id":5,
    "name":"name5",
    "items":
    [
      {"id":6,"name":"name6","valid":true},
      {"id":7,"name":"name7","valid":false}
    ]
  },
  {
    "id":8,
    "name":"name8",
    "items":
    [
      {"id":9,"name":"name9","valid":true},
      {"id":10,"name":"name10","valid":false},
      {"id":11,"name":"name11","valid":false},
      {"id":12,"name":"name12","valid":true}
    ]
  }
]

傅.java:

import java.io.FileReader;
import java.util.ArrayList;

import com.google.gson.Gson;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new Gson();
    TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class);
    System.out.println(gson.toJson(myTypes));
  }
}

class TypeDTO
{
  int id;
  String name;
  ArrayList<ItemDTO> items;
}

class ItemDTO
{
  int id;
  String name;
  Boolean valid;
}

第二个示例使用一个 JSON 结构,该结构实际上是“{TypeDTO 对象的数组,其中包含一个数组的 {ItemDTO 对象}}”,以匹配最初提供的 Java 数据结构。

input.json Contents:

[
  {
    "id":1,
    "name":"name1",
    "items":
    [
      [
        {"id":2,"name":"name2","valid":true},
        {"id":3,"name":"name3","valid":false}
      ],
      [
        {"id":4,"name":"name4","valid":true}
      ]
    ]
  },
  {
    "id":5,
    "name":"name5",
    "items":
    [
      [
        {"id":6,"name":"name6","valid":true}
      ],
      [
        {"id":7,"name":"name7","valid":false}
      ]
    ]
  },
  {
    "id":8,
    "name":"name8",
    "items":
    [
      [
        {"id":9,"name":"name9","valid":true},
        {"id":10,"name":"name10","valid":false}
      ],
      [
        {"id":11,"name":"name11","valid":false},
        {"id":12,"name":"name12","valid":true}
      ]
    ]
  }
]

傅.java:

import java.io.FileReader;
import java.util.ArrayList;

import com.google.gson.Gson;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new Gson();
    TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class);
    System.out.println(gson.toJson(myTypes));
  }
}

class TypeDTO
{
  int id;
  String name;
  ArrayList<ItemDTO> items[];
}

class ItemDTO
{
  int id;
  String name;
  Boolean valid;
}

关于剩下的两个问题:

Gson的速度非常快吗?

不与其他反序列化/序列化 API 进行比较。Gson传统上是最的。据报道,Gson的当前和下一个版本包括显着的性能改进,尽管我还没有寻找最新的性能测试数据来支持这些说法。

也就是说,如果Gson足够快地满足您的需求,那么由于它使JSON反序列化变得如此容易,因此使用它可能是有意义的。如果需要更好的性能,那么Jackson可能是更好的选择。它提供了Gson的许多(甚至可能全部)便利。

还是我最好坚持我已经工作的东西?

我不会。我总是宁愿有一行简单的代码,比如

TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class);

...轻松反序列化为复杂的数据结构,而不是一次将各个部分映射在一起所需的三十行代码。


答案 2

如果 JSON 数据以数组对象开头,请使用如下所示的 Bean 类。它可以帮助你。

Users[] bean = gson.fromJson(response,Users[].class);

用户是我的豆类。

响应是我的 JSON 数据。