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

Как использовать API Google Gson для десериализации JSON правильно?

Короче говоря, это эскиз объекта JSON, который я хочу проанализировать в JAVA:

{
    object1: {
            item1: //[String | Array | Object] ,
            item2: // ...
            //<> more items
    object2: { /* .. */ }
    //<> more objects
}

Это POJO, которые я создал для синтаксического анализа (я не буду приводить инструкции import для краткости):

(1) Представление полного объекта JSON

public class JObjectContainer {

    private List<JObject> jObjects ;

    public JObjectContainer() { }

    //get & set methods

}

(2) Представление вложенных объектов:

 public class JObject {

    private String id ;
    private List<JNode> jObjects ;

    public JObject() { } 

    //get & set methods

}

(3) Представление элементов:

 public class JNode {

    private JsonElement item1 ;
    private JsonElement item2 ;
    //<> more item fields

    public JNode() { }

    //get & set methods

}

Теперь, создав экземпляр Gson (FileReader для импорта jsonFile),

 Gson gson = new Gson() ;
 JObjectContainer joc = gson.fromJson(jsonFile,JObjectContainer.class) ;

Я получаю a NullPointerException всякий раз, когда пытаюсь получить доступ к анализируемому объекту (например, через ListIterator). Однако Gson создает объект указанного класса и не вызывает никаких последующих ошибок.

Я знаю, что это было сделано раньше. Итак, что мне не хватает?

ТИА

4b9b3361

Ответ 1

Это невозможно. Вам необходимо изменить структуру JSON для представления object1, object2 и т.д. В качестве элементов массива . Прямо сейчас это свойства объекта, из которого он, по-видимому, неизвестно, сколько из них будет (иначе вы не пытались сопоставить его как List). Gson умный, но не тот умный:)

Итак, в качестве основного примера эта структура JSON с массивом:

{ nodes:
  [
    { item1: 'value1a', item2: 'value2a' },
    { item1: 'value1b', item2: 'value2b' },
    { item1: 'value1c', item2: 'value2c' }
  ]
}

в сочетании с представлением Java (которое необязательно должно называться POJO, а просто javabean или объект модели или объект значения).

public class Container {
    private List<Node> nodes;
    // +getter.
}

public class Node {
    private String item1;
    private String item2;
    // +getters.
}

и этот вызов Gson

Container container = new Gson().fromJson(json, Container.class);

должен работать.

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

{ jObjects:
  [
    { id: 123, jObjects: 
      [
        { item1: 'value1a', item2: 'value2a' },
        { item1: 'value1b', item2: 'value2b' },
        { item1: 'value1c', item2: 'value2c' }
        /* etc... commaseparated */
      ]
    },
    { id: 456, jObjects: 
      [
        { item1: 'value1d', item2: 'value2d' },
        { item1: 'value1e', item2: 'value2e' },
        { item1: 'value1f', item2: 'value2f' }
        /* etc... commaseparated */
      ]
    }
    /* etc... commaseparated */
  ]
}

Только свойство JsonElement должно быть заменено на String, так как оно недействительно.

Ответ 2

Я думаю, что BalusC дал хорошие указатели на конкретный вопрос по GSon (и, в общем, привязку данных один к одному); но на всякий случай вы думаете, что должно быть более динамичное управление, вы также можете рассмотреть другие пакеты обработки JSON. У многих пакетов есть дополнительные или альтернативные способы сопоставления вещей: у Json-lib, flexjson и Jackson есть дополнения по сравнению с Gson. Некоторые предлагают более легкое сопоставление (вы определяете имена вещей для типов), другие - фактическую поддержку полиморфных типов (объявление объекта, но может фактически отображаться в подтипе, который был сериализован).