Десериализация родовых коллекций с помощью Gson - PullRequest
3 голосов
/ 19 июня 2011

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

Я хочу десериализовать следующий фрагмент json:

{
    "fieldA": "valueA",
    "myCollection": {
        "AnotherClass": [
            {
                "objectAfieldA": "valueB",
                "objectAfieldB": "valueC"
            },
            {
                "objectAfieldA": "valueD",
                "objectAfieldB": "valueE"
            }
        ]
    }
}

соответствующий общий класс имеет следующие поля:

...
String fieldA;
List<AnotherClass> = new ArrayList<AnotherClass>();
....

Теперь моя проблема в том, что когда я десериализую, используя fromJson(jsonSample, resultContainer.class), без элемента List<T>, все хорошо, но я получаю NullPointerException, когда включаю содержащийся список. Я читал о том, как обращаться с коллекциями универсальных типов и использованием TypeToken, но я не могу применить эти знания, когда моя коллекция является частью другого класса ...

Я бы очень признателен за помощь в решении этой проблемы.

Ответы [ 2 ]

4 голосов
/ 26 сентября 2012

Решение для десериализации безымянного массива JSON довольно просто:

List<resultContainer> lres = gson.fromJson(new FileReader("input.json"), new TypeToken<List<resultContainer>>(){}.getType());
2 голосов
/ 19 июня 2011

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

Похоже, проблема в том, что структура JSON не соответствует структуре Java, пытающейся привязаться к ней.

Структура JSON определяет

an object with two elements
    element 1 is a string named "fieldA",
    element 2 is an object named "myCollection", which has one element
        the one element is an array named "AnotherClass", composed of objects with two elements
            element 1 is a string named "objectAfieldA",
            element 2 is a string named "objectAfieldB"

Итак, определите структуру данных Java, чтобы соответствовать этому, и десериализация будет работать очень просто, без какой-либо специальной обработки.Если такая подходящая структура Java не предоставлена, тогда необходима пользовательская десериализация.

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

import java.io.FileReader;

import com.google.gson.Gson;

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

class resultContainer
{
  String fieldA;
  MyCollectionContainer myCollection;
}

class MyCollectionContainer
{
  SomeOtherClass[] AnotherClass;
}

class SomeOtherClass
{
  String objectAfieldA;
  String objectAfieldB;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...