Подтвердить что ты не робот

Gson и десериализация массива объектов с массивами в нем

Я пытаюсь использовать Gson для десериализации строки json, возвращаемой из моего webservice

Структура будет возвращена как 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);

Все внутри объектов равно null

Однако, если я использую

JSONArray и JSONObject, чтобы вытащить их по частям из банки org.json, он отлично работает, и поля заполняются соответствующим образом.

Любые идеи относительно того, что я делаю неправильно? Гэн очень быстро? Или мне лучше придерживаться того, что у меня уже есть?

Спасибо, Дэвид

4b9b3361

Ответ 1

Пример структуры данных Java в исходном вопросе не соответствует описанию структуры JSON в комментарии.

JSON описывается как

"массив {объект с массивом {object}}".

В терминах типов, описанных в вопросе, JSON, переведенный в структуру данных Java, которая будет соответствовать структуре JSON для легкой десериализации с Gson,

"массив объекта {TypeDTO с массивом {ItemDTO object}}".

Но структура данных Java, предоставленная в вопросе, не такова. Вместо этого он

"массив объекта {TypeDTO с массивом массива {ItemDTO object}}".

Двумерный массив!= одномерный массив.

Этот первый пример демонстрирует использование Gson для просто десериализации и сериализации структуры JSON, которая представляет собой "массив из {объекта с массивом {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, которая на самом деле представляет собой "массив объекта TypeDTO с массивом из массива {ItemDTO object}}", чтобы соответствовать первоначально предоставленной структуре данных Java.

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 настолько простой, возможно, имеет смысл использовать ее. Если требуется более высокая производительность, то Джексон может быть лучшим выбором для использования. Он предлагает много (может быть, даже все) удобств Gson.

Или мне лучше придерживаться того, что у меня уже есть?

Я бы не стал. Я бы всегда предпочитал одну простую строку кода, например

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

... чтобы легко десериализоваться в сложную структуру данных, чем тридцать строк кода, которые в противном случае были бы необходимы для одновременного отображения частей вместе по одному компоненту.