Я запрашиваю данные с сервера, который возвращает данные в формате JSON. Встраивание HashMap в JSON при выполнении запроса совсем не сложно, но другой способ кажется немного сложным. Ответ JSON выглядит следующим образом:
{
"header" : {
"alerts" : [
{
"AlertID" : "2",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
},
{
"AlertID" : "3",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
}
],
"session" : "0bc8d0835f93ac3ebbf11560b2c5be9a"
},
"result" : "4be26bc400d3c"
}
Каким способом было бы проще всего получить доступ к этим данным? Я использую модуль GSON.
Map<String,Object> result = new Gson().fromJson(json, Map.class);
работает с gson 2.6.2.Ответы:
Ну вот:
источник
TypeToken
- он делает неявное приведение внутри.{"k1":"apple","k2":"orange"}
Этот код работает:
источник
Map<String, Object>
потому что, если json не только строки, вы получаете ошибкуTypeToken
.Я знаю, что это довольно старый вопрос, но я искал решение для общей десериализации вложенного JSON в a
Map<String, Object>
и ничего не нашел.Как работает мой десериализатор yaml, он по умолчанию устанавливает объекты JSON,
Map<String, Object>
когда вы не указываете тип, но, похоже, gson этого не делает. К счастью, вы можете сделать это с помощью специального десериализатора.Я использовал следующий десериализатор для естественной десериализации чего-либо, по умолчанию
JsonObject
sMap<String, Object>
иJsonArray
s кObject[]
s, где все дочерние элементы аналогично десериализованы.Беспорядок в
handlePrimitive
методе предназначен для того, чтобы убедиться, что вы когда-нибудь получите только Double, Integer или Long, и, возможно, могли бы быть лучше или, по крайней мере, упрощены, если у вас все в порядке с получением BigDecimals, который я считаю по умолчанию.Вы можете зарегистрировать этот адаптер как:
И затем назовите это как:
Я не уверен, почему это не поведение по умолчанию в gson, так как это происходит в большинстве других частично структурированных библиотек сериализации ...
источник
С gson 2.7 от Google (возможно, и с более ранними версиями, но я тестировал с текущей версией 2.7) это так просто:
Который возвращает
Map
типcom.google.gson.internal.LinkedTreeMap
и работает рекурсивно на вложенных объектах, массивах и т. Д.Я запустил пример OP следующим образом (просто заменил double-одинарными кавычками и удалил пробелы):
И получил следующий вывод:
источник
Обновление для новой библиотеки Gson:
теперь вы можете анализировать вложенный Json в Map напрямую, но вам следует знать об этом, если вы попытаетесь проанализировать Json для
Map<String, Object>
ввода: это вызовет исключение. Чтобы это исправить, просто объявите результат какLinkedTreeMap
тип. Пример ниже:источник
Map<String,Object> result = gson.fromJson(json , Map.class);
. Использование gson 2.6.2.У меня был точно такой же вопрос, и я оказался здесь. У меня был другой подход, который кажется гораздо проще (может быть, новые версии GSON?).
со следующим JSON
Последующий
выходы
Вы можете динамически проверять использование instanceof при навигации по вашему jsonObject. Что-то вроде
Это работает для меня, так что это должно работать для вас ;-)
источник
Ниже поддерживается gson 2.8.0
источник
Попробуйте это, это будет работать. Я использовал это для Hashtable .
Замените KioskStatusResource на ваш класс и Integer на ваш ключевой класс.
источник
Вот что я использовал:
источник
Вот одна строка, которая сделает это:
источник
new TypeToken<HashMap<String, Object>>(){}
создаст новый встроенный подкласс, и все линтеры будутЯ преодолел аналогичную проблему с пользовательским JsonDeSerializer. Я попытался сделать это немного общим, но все еще недостаточно. Это решение, хотя и соответствует моим потребностям.
Прежде всего, вам необходимо реализовать новый JsonDeserializer для объектов Map.
И метод десериализации будет выглядеть примерно так:
Недостаток этого решения в том, что ключ моей карты всегда имеет тип «String». Однако, изменяя некоторые вещи, кто-то может сделать это общим. Кроме того, я должен сказать, что класс значения должен быть передан в конструкторе. Таким образом, метод
getMyType()
в моем коде возвращает тип значений Map, который был передан в конструктор.Вы можете сослаться на этот пост Как мне написать собственный десериализатор JSON для Gson? чтобы узнать больше о пользовательских десериализаторах.
источник
Вместо этого вы можете использовать этот класс :) (обрабатывает даже списки, вложенные списки и json)
Чтобы преобразовать вашу строку JSON в hashmap, используйте это:
источник
Это скорее дополнение к ответу Кевина Долана, чем полный ответ, но у меня возникли проблемы с извлечением типа из числа. Это мое решение:
источник
источник
JSONObject обычно использует
HashMap
внутренне для хранения данных. Таким образом, вы можете использовать его как карту в вашем коде.Пример,
источник
Я использовал этот код:
источник