Gson并反序列化带有数组的对象数组


71

我正在尝试使用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并将JSONObject它们从org.json罐子中逐段拉出,效果很好,并相应地填充了字段。

关于我在做什么错的任何想法吗?Gson非常快吗?还是我最好坚持自己已经做的工作​​?

谢谢大卫


您需要提供更多信息。您收到的JSON的格式是什么?为什么你有一个数组的ArrayListTypeDTO?吉森(Gson)很好地处理了这种事情。
ColinD

我以为我给出了JSON的清晰图片。顶层是对象列表。每个对象具有多个kv对,其中一个是具有更多kv对的另一对象列表。
DavieDave

@daviedave:我认为程序员-布鲁斯的答案值得标记为接受
Sumit Ramteke 2014年

Answers:


128

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

JSON被描述为

“ {object数组与{object}数组}”。

根据问题中描述的类型,将JSON转换为与JSON结构匹配的Java数据结构,以便通过Gson轻松反序列化。

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

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

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

二维数组!=一维数组。

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

input.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:

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结构来匹配最初提供的Java数据结构,该JSON结构实际上是“ {TypeDTO对象的数组和{ItemDTO对象}的数组}的数组”。

input.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:

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

...要轻松地反序列化为复杂的数据结构,则需要三十行代码,否则需要三十行代码才能将片段一次映射到一个组件上。


感谢您的解决方案,在徒劳地尝试了三个小时之后,您的方法才是我发现的最好方法。
Awemo

9
@Programmer Bruce +1表示“宁可只有一行简单的代码”。GSON的功能不是解析的速度,而是编写和维护大量生产案例所需的代码的速度。而且,当您需要优化时,GSON的流传输模型确实可以极大地提高性能。
理查德·勒·马苏里尔

1

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

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

用户是我的bean类。

响应是我的JSON数据。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.