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

时间:2022-06-12 17:07:21

I am trying to use Gson to deserialize a json string returned from my webservice

我正在尝试使用Gson对webservice返回的json字符串进行反序列化

The structure would be returned as TypeDTO[].

结构将返回为TypeDTO[]。

where TypeDTO is like

TypeDTO哪里像

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

and ItemDTO is like

和ItemDTO就像

int id;
String name;
Boolean valid;

When I call the code as follows

当我按如下方式调用代码时

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

Everything inside the objects is null

对象内部的所有东西都是空的

However, If I use the

但是,如果我用

JSONArray and JSONObject to pull them out piece by piece from the org.json jars, it works fine and the fields are populated accordingly.

JSONArray和JSONObject将它们从org中逐个取出。json jar,它工作得很好,并相应地填充字段。

Any ideas as to what I'm doing wrong? is Gson extremely fast? Or am I better to stick with what I've got working already?

你知道我做错了什么吗?是Gson非常快?还是我应该继续做我已经在做的事情?

Thanks, David

谢谢你,大卫

2 个解决方案

#1


103  

The example Java data structure in the original question does not match the description of the JSON structure in the comment.

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

The JSON is described as

JSON被描述为

"an array of {object with an array of {object}}".

“带有{object}}数组的{对象数组”。

In terms of the types described in the question, the JSON translated into a Java data structure that would match the JSON structure for easy deserialization with Gson is

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

"an array of {TypeDTO object with an array of {ItemDTO object}}".

“一组{TypeDTO对象数组{ItemDTO object}}”。

But the Java data structure provided in the question is not this. Instead it's

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

"an array of {TypeDTO object with an array of an array of {ItemDTO object}}".

“{TypeDTO对象的数组,带有{ItemDTO对象}的数组”。

A two-dimensional array != a single-dimensional array.

二维数组!=单维数组。

This first example demonstrates using Gson to simply deserialize and serialize a JSON structure that is "an array of {object with an array of {object}}".

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

input.json Contents:

输入。json内容:

[
  {
    "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:

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

This second example uses instead a JSON structure that is actually "an array of {TypeDTO object with an array of an array of {ItemDTO object}}" to match the originally provided Java data structure.

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

input.json Contents:

输入。json内容:

[
  {
    "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:

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

Regarding the remaining two questions:

关于其余两个问题:

is Gson extremely fast?

是Gson非常快?

Not compared to other deserialization/serialization APIs. Gson has traditionally been amongst the slowest. The current and next releases of Gson reportedly include significant performance improvements, though I haven't looked for the latest performance test data to support those claims.

与其他反序列化/序列化api不同。Gson一直是最慢的。据报道,Gson的当前和下一个版本包含了显著的性能改进,尽管我还没有寻找最新的性能测试数据来支持这些断言。

That said, if Gson is fast enough for your needs, then since it makes JSON deserialization so easy, it probably makes sense to use it. If better performance is required, then Jackson might be a better choice to use. It offers much (maybe even all) of the conveniences of Gson.

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

Or am I better to stick with what I've got working already?

还是我应该继续做我已经在做的事情?

I wouldn't. I would most always rather have one simple line of code like

我不会。我宁愿只写一行简单的代码

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

...to easily deserialize into a complex data structure, than the thirty lines of code that would otherwise be needed to map the pieces together one component at a time.

…要轻松反序列化成复杂的数据结构,需要三十行代码,否则每次只能将各个部分映射到一个组件。

#2


0  

Use your bean class like this, if your JSON data starts with an an array object. it helps you.

如果JSON数据以数组对象开头,则使用这样的bean类。它可以帮助你。

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

Users is my bean class.

用户是我的bean类。

Response is my JSON data.

响应是我的JSON数据。

#1


103  

The example Java data structure in the original question does not match the description of the JSON structure in the comment.

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

The JSON is described as

JSON被描述为

"an array of {object with an array of {object}}".

“带有{object}}数组的{对象数组”。

In terms of the types described in the question, the JSON translated into a Java data structure that would match the JSON structure for easy deserialization with Gson is

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

"an array of {TypeDTO object with an array of {ItemDTO object}}".

“一组{TypeDTO对象数组{ItemDTO object}}”。

But the Java data structure provided in the question is not this. Instead it's

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

"an array of {TypeDTO object with an array of an array of {ItemDTO object}}".

“{TypeDTO对象的数组,带有{ItemDTO对象}的数组”。

A two-dimensional array != a single-dimensional array.

二维数组!=单维数组。

This first example demonstrates using Gson to simply deserialize and serialize a JSON structure that is "an array of {object with an array of {object}}".

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

input.json Contents:

输入。json内容:

[
  {
    "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:

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

This second example uses instead a JSON structure that is actually "an array of {TypeDTO object with an array of an array of {ItemDTO object}}" to match the originally provided Java data structure.

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

input.json Contents:

输入。json内容:

[
  {
    "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:

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

Regarding the remaining two questions:

关于其余两个问题:

is Gson extremely fast?

是Gson非常快?

Not compared to other deserialization/serialization APIs. Gson has traditionally been amongst the slowest. The current and next releases of Gson reportedly include significant performance improvements, though I haven't looked for the latest performance test data to support those claims.

与其他反序列化/序列化api不同。Gson一直是最慢的。据报道,Gson的当前和下一个版本包含了显著的性能改进,尽管我还没有寻找最新的性能测试数据来支持这些断言。

That said, if Gson is fast enough for your needs, then since it makes JSON deserialization so easy, it probably makes sense to use it. If better performance is required, then Jackson might be a better choice to use. It offers much (maybe even all) of the conveniences of Gson.

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

Or am I better to stick with what I've got working already?

还是我应该继续做我已经在做的事情?

I wouldn't. I would most always rather have one simple line of code like

我不会。我宁愿只写一行简单的代码

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

...to easily deserialize into a complex data structure, than the thirty lines of code that would otherwise be needed to map the pieces together one component at a time.

…要轻松反序列化成复杂的数据结构,需要三十行代码,否则每次只能将各个部分映射到一个组件。

#2


0  

Use your bean class like this, if your JSON data starts with an an array object. it helps you.

如果JSON数据以数组对象开头,则使用这样的bean类。它可以帮助你。

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

Users is my bean class.

用户是我的bean类。

Response is my JSON data.

响应是我的JSON数据。