проблемы с разбором json - PullRequest
0 голосов
/ 05 июля 2011
 data: [
        { 
         type: "earnings" 
         info: { 
                earnings: 45.6 
                dividends: 4052.94 
                gains: 0 
                expenses: 3935.24 
                shares_bought: 0 
                shares_bought_user_count: 0 
                shares_sold: 0 
                shares_sold_user_count: 0 
               } 
         created: "2011-07-04 11:46:17" 
        }
        { 
         type: "mentions" 
         info: [ 
                { 
                 type_id: "twitter" 
                 mentioner_ticker: "LOANS" 
                 mentioner_full_name: "ERICK STROBEL" 
                } 
               ] 
         created: "2011-06-10 23:03:02" 
        }
       ]

Вот моя проблема: как вы можете видеть, что «информация» различна для каждого из них, один - это объект json, а другой - массив json, я обычно выбираю Gson для получения данных, но с помощью Gson мы можем: делать такие вещи. Как я могу заставить это работать?

Ответы [ 5 ]

1 голос
/ 05 июля 2011

Если вы хотите использовать Gson, то для решения проблемы, когда одно и то же значение элемента JSON иногда представляет собой массив, а иногда объект, необходима специальная обработка десериализации.Я опубликовал пример этого в Парсинг JSON с GSON, объект иногда содержит список, иногда содержит объект post.

Если объект элемента "info" имеет разные элементы в зависимости от типа, и поэтомувы хотите, чтобы поведение полиморфной десериализации десериализовалось до правильного типа объекта, а с Gson вам также потребуется реализовать пользовательскую обработку десериализации.Как это сделать, было описано в других статьях StackOverflow.com.Я разместил ссылку на четыре разных таких вопроса и ответов (некоторые с примерами кода) в Могу ли я создать экземпляр суперкласса и создать конкретный подкласс на основе предоставленных параметров потока .В этом потоке конкретная структура десериализованных объектов JSON отличается от только что приведенных мною примеров, поскольку элемент, указывающий тип, является внешним по отношению к десериализуемому объекту, но если вы понимаете другие примеры, то решите проблемуздесь должно быть легко.

0 голосов
/ 05 июля 2011

Используйте просто классы org.json, которые доступны в Android: http://developer.android.com/reference/org/json/package-summary.html

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

Это не «обычный» способ ведения дел в Java (где строгая типизация используется по умолчанию), но IMHO во многих ситуациях, даже в Java, нормально выполнять некоторую динамическую обработку. Гибкость лучше, но цена за нее - отсутствие проверки типа во время компиляции ... Что во многих случаях нормально.

0 голосов
/ 05 июля 2011

Объект info должен быть одного типа с каждым типом .Поэтому сначала проверьте type.Псевдокод:

if (data.get('type').equals("mentions") {
    json_arr = data.get('info');
}
else if (data.get('type').equals("earnings") {
    json_obj = data.get('info');
}

Я не уверен, что это помогает, потому что я не уверен, что понимаю вопрос.

0 голосов
/ 05 июля 2011

Если вы хотите изменить библиотеки, вы можете взглянуть на Джексона, его режим Simple Data Binding должен позволить вам десериализовать объект, как вы описали.Часть документа, которая, вероятно, весьма важна, это этот , вашему примеру уже понадобится JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES для работы ...

Уточнение для Брюса: правда, в режиме полного связывания данных Джексона, но не в режиме простого связывания данных.Это простое связывание данных:

public static void main(String[] args) throws IOException {
    File src = new File("test.json");
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(JsonParser.Feature. ALLOW_UNQUOTED_FIELD_NAMES, true);
    mapper.configure(JsonParser.Feature.ALLOW_COMMENTS,true);

    Object root = mapper.readValue(src, Object.class);
    Map<?,?> rootAsMap = mapper.readValue(src, Map.class);
    System.out.println(rootAsMap);
}

, которое с визуально исправленными выборочными данными JSON OP дает:

{data=[{type=earnings, info={earnings=45.6, dividends=4052.94, gains=0,
expenses=3935.24, shares_bought=0, shares_bought_user_count=0, shares_sold=0,
shares_sold_user_count=0}, created=2011-07-04 11:46:17}, {type=mentions,
info=[{type_id=twitter, mentioner_ticker=LOANS, mentioner_full_name=ERICK STROBEL}],
created=2011-06-10 23:03:02}]}

ОК, для ручной привязки этой карты к исходным данным требуется некоторое ручное кодирование., но нередко меньше - это больше, и такой код отображения, будучи очень простым, имеет то преимущество, что впоследствии его очень легко читать / поддерживать.

0 голосов
/ 05 июля 2011

Ключ и значение должны быть в кавычках, а определения необходимо разделять запятыми:

{ 
  "key0": "value0", 
  "key1": "value1", 
  "key2": [ "value2_0", "value2_1" ] 
}

Это должно сработать!

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