2010-05-19 4 views
19

Короче говоря, это эскиз объекта JSON Я хочу разобрать в JAVA:Как использовать Gson API Google для десериализации JSON правильно?

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

Таковы POJO s я создал для разбора (я оставлю вне 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) ; 

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

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

TIA

ответ

33

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

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

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

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

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, поскольку он недействителен.

+1

Привет, спасибо за ваш ответ! Я намеревался поддерживать строки идентификатора (например, «Object1»), чтобы иметь возможность правильно анализировать класс Container для его содержимого, как и в JavaScript. Вы знаете, как это сделать? – FK82

+0

Если эти строки идентификатора привязаны к каждому элементу ('Node'), а не к контейнеру (' nodes'), тогда вам нужно сделать его свойством 'Node'. Объекты JS с неизвестным количеством свойств и неизвестными именами свойств просто не являются хорошей идеей/практикой. Вам нужно поместить их в массив и дать массиву фиксированное имя. – BalusC

+0

Этот вид превосходит цель использования JSON в целом. Если я не могу отразить стиль отображения объектов JSON в JAVA, я мог бы написать собственный API. ;-) Я в основном пытаюсь сделать то же самое, что и в этом example while somehow retaining the identifier strings. – FK82

0

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

+0

Привет, спасибо за ваш ответ. На самом деле, я не был так уверен в том, как GSON работает внутри страны и, следовательно, не совсем понимает, как его использовать. Теперь я использую собственный синтаксический анализ с Rhino, что, на мой взгляд, гораздо удобнее. Java не поддерживает вложенные объекты данных таким же простым способом, как это делает JavaScript, поэтому нет реальной причины не использовать Rhino для такого рода вещей. – FK82