并反序列化包含数组的对象数组

我正在尝试使用 Gson 对从我的 webservice 返回的 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);

对象中的一切都是空的

但是,如果我使用

JSONArrayJSONObject将它们从 org.json 罐子中一块一块地提取出来,它工作得很好,并相应地填充字段。

知道我哪里做错了吗 Gson 速度很快吗? 还是我应该继续我的工作?

谢谢, 大卫

148187 次浏览

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

JSON 被描述为

“一个{ object 的数组和一个{ object }的数组”。

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

“{ TypeDTO 对象的数组和{ ItemDTO 对象}}的数组”。

但是问题中提供的 Java 数据结构不是这个,而是

“{ TypeDTO 对象的数组和{ ItemDTO 对象}的数组”。

二维数组! = 一维数组。

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

目录:

[
{
"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}
]
}
]

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

第二个示例使用实际上是“一个{ TypeDTO 对象数组和一个{ ItemDTO 对象}}数组”的 JSON 结构来匹配最初提供的 Java 数据结构。

目录:

[
{
"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}
]
]
}
]

Foo.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 反序列化非常容易,因此使用它可能是有意义的。如果需要更好的表现,那么杰克逊可能是一个更好的选择。它提供了 Gson 的许多(甚至可能是全部)便利条件。

还是我应该继续我的工作?

我不会这么做,我更希望只有一行简单的代码,比如

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

... 很容易反序列化为一个复杂的数据结构,而不是三十行代码,否则就需要把这些片段一次一个组件地映射到一起。

如果您的 JSON 数据以一个数组对象开始,可以像这样使用 bean 类。

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

用户是我的 bean 类。

响应是我的 JSON 数据。