Как конвертировать строку String в объект JSON в Java?
В настоящее время очень распространено получать JSON String от веб-службы Java вместо XML, но, к сожалению, JDK еще не поддерживает преобразование между JSON String в объект JSON.
Сохранение JSON в качестве String не всегда является хорошим вариантом, поскольку вы не можете легко с ним работать, вам нужно преобразовать его в объект JSON, прежде чем делать что-либо еще, например. получить любое поле или установить разные значения.
Существует много библиотек с открытым исходным кодом, которые позволяют создавать JSON-объекты из форматированной строки JSON, например, Gson от Google, Jackson или просто JSON.
В этом руководстве вы узнаете, как конвертировать и преобразовать строку String в JsonObject, используя 3 основные библиотеки.
Будем использовать следующую строку JSON для примера:
Это просто, который имеет 5 атрибутов, два из которых являются String, а два других являются числовыми. Одним из атрибутов lastScore является массив JSON.
Преобразование строки в объект JSON с использованием Gson
Gson – это библиотека с открытым исходным кодом для работы с JSON в программах Java. Он создан Google, который также стоит за Guava, библиотекой общего назначения для Java-программистов.
Вы можете конвертировать JSON String в объект Java всего за 2 строки, используя Gson, как показано ниже:
Или преобразовать Java-объект в JSON с помощью метода toJson (), как показано ниже:
Если вы не очень хорошо знакомы с самим форматом JSON, я бы посоветовал прочитать «Beginning JSON» от Ben Smit, чтобы узнать больше.
Конвертирование JSON в объект Java
JSON-Simple – это еще одна библиотека с открытым исходным кодом, которая поддерживает синтаксический анализ и форматирование JSON. У нее небольшой размер, который идеально подходит для сред с ограниченной памятью, таких как J2ME и Android.
Полезной особенностью json-simple является то, что она также совместима с JDK 1.2, что означает, что вы можете использовать ее в устаревшем проекте, который еще не в Java 5.
Библиотека Jackson
Jackson, я думаю, самая популярная библиотека синтаксического анализа JSON в мире Java. Она быстрая, многофункциональная и поддерживает потоковую передачу, что отлично подходит для анализа больших выходных данных JSON из веб-сервисов.
С помощью одной строки, вы можете преобразовать строку JSON, представляющую футболиста, в класс Java, представляющий игрока:
Один из недостатков Jackson заключается в том, что для него требуется JDK 1.5, поэтому, если вы застряли в более ранней версии Java, он может там не работать.
Jackson не поддерживает J2ME, но одно из главных преимуществ использования заключается в том, что он поддерживает потоковую передачу, которую можно использовать для анализа большого ответа JSON без полной загрузки его в память.
Вы можете использовать любую из библиотек: json-simple, Gson или Jackson для анализа JSON, полученных от веб-сервисов, каждое из которых имеет свои преимущества.
- Json-simple имеет небольшой объем памяти и он вполне подходит для J2ME и Android.
- Jackson обладает богатым набором функций, поэтому лучше применять для большого проекта.
- Gson находится между ними и применим для общего назначения в программах Java.
Средняя оценка / 5. Количество голосов:
Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.
Или поделись статьей
Видим, что вы не нашли ответ на свой вопрос.
Источник
Android — JSON Parser
JSON означает JavaScript Object Notation. Это независимый формат обмена данными и лучшая альтернатива XML. В этой главе объясняется, как анализировать файл JSON и извлекать из него необходимую информацию.
Android предоставляет четыре различных класса для управления данными JSON. Это классы JSONArray, JSONObject, JSONStringer и JSONTokenizer.
Первым шагом является определение полей в данных JSON, в которых вы заинтересованы. Например. В приведенном ниже JSON мы заинтересованы только в получении температуры.
JSON — Элементы
Файл JSON состоит из множества компонентов. Вот таблица, определяющая компоненты файла JSON и их описание —
Sr.No | Компонент и описание | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 |
Sr.No | Метод и описание | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | |||||||||||||
4 | getInt (Строковое имя) Этот метод возвращает целочисленное значение, указанное ключом getLong (имя строки) Этот метод возвращает длинное значение, указанное ключом Этот метод возвращает количество отображений имени / значения в этом объекте. Этот метод возвращает массив, содержащий имена строк в этом объекте. получить (строковое имя) Этот метод просто возвращает значение, но в форме типа объекта getBoolean (имя строки) Этот метод возвращает логическое значение, указанное ключом getDouble (имя строки) Этот метод возвращает двойное значение, указанное ключом Этот метод возвращает целочисленное значение, указанное ключом getLong (имя строки) Этот метод возвращает длинное значение, указанное ключом Этот метод возвращает количество отображений имени / значения в этом объекте. Этот метод возвращает массив, содержащий имена строк в этом объекте. примерЧтобы поэкспериментировать с этим примером, вы можете запустить его на реальном устройстве или в эмуляторе.
Ниже приводится содержимое измененного основного файла активности src / MainActivity.java . Ниже приведено измененное содержимое XML- файла HttpHandler.java . Ниже приводится измененное содержимое файла xml res / layout / activity_main.xml . Ниже приведено измененное содержимое xml res / layout / list_item.xml . Ниже приводится содержимое файла AndroidManifest.xml . Давайте попробуем запустить наше приложение, которое мы только что изменили. Я предполагаю, что вы создали свой AVD во время настройки среды. Чтобы запустить приложение из студии Android, откройте один из файлов деятельности вашего проекта и нажмите «Выполнить». Приведенный выше пример, показывающий данные из строки json, содержит данные работодателя, а также информацию о зарплате. Источник Gson или «Туда и Обратно»Недавно мне пришлось поработать с библиотекой Google Gson, предназначенной для преобразования Java-объектов в текстовый формат JSON (сериализация) и обратного преобразования (десереализация). Часто при работе с Gson хватает стандартных настроек библиотеки, но бывают случаи (в том числе мой), когда необходимо кастомизировать процессы преобразований. Поработав с Gson, я решил написать этот туториал, который иллюстрирует принципы работы с библиотекой на примере. Пост получился сравнительно длинный, но дробить его не хочется из-за логической связности повествования. Для начала нужно выбрать какую-нибудь предметную область. Скажем, не знаю, почему-то приходят в голову мысль про отряд гномов. Собственно, почему бы и нет?
Да, весь код, задействованный в статье, можно найти на GitHub: https://github.com/treble-snake/gson.dwarves ВведениеО гномахИтак, с «отрядом» понятно — это некое множество гномов. Но что насчет самих гномов? Самая важная деталь, характеризующая гнома — это, конечно, борода. Можно долго расписывать особенности и классификации гномьих бород, но для простоты определим три параметра: есть ли у гнома усы, есть ли борода, и какого они цвета. Далее, имя и возраст — куда ж без них. Добавим еще что-нибудь личного, скажем, что гном ел на обед. Ну и, наконец, оружие. Оружия у гнома может быть много, причем оно может быть простое, а может быть уникальное, имеющее собственное имя и происхождение. В итоге получается примерно так: Для краткости приведу все классы в одном листинге: Проинициализируем нашу гномью компанию, добавив трех участников (все действующие лица вымышлены, а совпадения случайны): По умолчаниюИтак, мы хотим получить информацию о наших гномах в формате JSON. Попробуем самый простой способ — использовать стандартные параметры библиотеки Gson, создав экземпляр одноименного класса и вызвав метод toJson() . Собственно, экземпляр класса Gson можно было создать и через оператор new , но тогда выходной JSON был бы не отформатирован, что хорошо для обмена данными между приложениями (быстрее формируется, меньше весит), но не здорово для человеческого восприятия. Поэтому мы использовали специальный GsonBuilder, вызвав метод setPrettyPrinting() , который позволил лицезреть выходной JSON в следующем виде: Что ж, с этим уже можно работать, однако, если подумать, то есть несколько замечаний:
Если учесть все замечания, то мы хотим видеть информацию о гноме в таком формате: АннотацииGson предоставляет нам несколько полезных аннотаций для настройки сериализации. Посмотрим, смогут ли они помочь нам. С первой проблемой — да, изменить выходное имя свойства мы можем, добавив аннотацию SerializedName к соотв. полю класса. То есть, сделав так: Мы получим на выходе свойство с именем «age» вместо «dwarfAge». Уже неплохо, идем дальше. Нужно исключить поле lunch . Во-первых, сделать это можно, добавив к нему ключевое слово transient, в таком случае поле не будет учитываться при сериализации. Но не факт, что это правильный путь. То, что информация про обед не нужна нам здесь, не значит, что она не нужна при какой-то иной сериализации. Свой сериализаторБолее гибкий способ — создать свой класс, производящий сериализацию объектов определенного типа. Для этого необходимо реализовать интерфейс JsonSerializer , где T — тип обрабатываемых объектов. Рассмотрим единственный метод serialize() интерфейса: Он принимает три параметра:
Возвращаемый тип данных метода — JsonElement . Это абстрактный класс, имеющий 4 реализации, изображенные на рисунке ниже:
На рисунке ниже изображен пример сочетания типов: Время сериализовать гномовИтак, довольно теории, давайте же наконец сериализовать! Соответственно, нам нужны две реализации JsonSerializer . Выглядят они вполне аналогично: Чтобы при обработке гномов Gson использовал наши сериализаторы, нужно зарегистрировать его с помощью метода registerTypeAdapter() класса GsonBuilder следующим образом: Борода и усыРеализуем для начала обработку бороды и усов. Ниже приведен полный код, который далее разберем подробней: Все довольно просто. Так как информацию о бороде и усах мы сводим к одной строке, то результатом работы метода serialize() должен являться объект JsonPrimitive , содержащий нужную строку. В ином случае, используя довольно тривиальный алгоритм, получим из исходных данных строку нужного нам вида, и также создадим на её основе экземпляр JsonPrimitive . И да, примем за данность, что входной объект и цвет волос у нас всегда проинициализированы, чтобы не усложнять код проверками, совершенно неважными для обучающих целей статьи. Сам гномТеперь реализуем обработку гнома целиком (также опустим проверки): Разберем этот код по частям. Так как в результате мы должны получит JSON-объект, то создаем переменную соответствующего типа: Затем с помощью метода addProperty() заносим в наш объект данные примитивных типов (не создавая при этом промежуточный JsonPrimitive -объект). Передаем в метод два параметра: первый — ключ, то есть название свойства JSON-объекта, второй — собственно, значение этого свойства. Здесь-то мы и задаем имя свойства «age» вместо «dwarfAge», а также исключаем из результата информацию про обед — просто не добавляя её в результирующий объект. Далее нам нужно добавить данные о бороде. Для этого мы используем метод serialize() контекста — как говорилось ранее, контекст осведомлен о зарегистрированных сериализаторах, поэтому для класса FacialHair применит наш FacialHairSerializer . Получившийся JsonElement мы добавляем к нашему объекту методом add(), указав нужное имя свойства. Осталось только добавить информацию об оружии гнома. Так как никаких символьных ключей для единиц оружия у нас не предусмотрено, то для их хранения создаем экземпляр JsonArray и добавляем его в наш объект с помощью того же метода add(). Теперь нужно наполнить созданный массив элементами. У класса JsonArray тоже есть метод add(), но он принимает только один параметр типа JsonElement , что и логично — ключ в данном случае не нужен. При добавлении обычного оружия создаем JsonPrimitive на основе строки, а уникальное сериализуем с помощью контекста. В данном случае сработает стандартный механизм сериализации, потому что никаких обработчиков для класса UniqueWeapon мы не регистрировали. РезультатНаконец, используем плод нашего труда по прямому назначению: Смотрим, что у нас получилось: Последний штрихЕдинственное, что хотелось бы изменить — все гномы у нас являются элементами массива, который хранится в свойстве «dwarves». Это как-то несолидно, да и избыточно — мы же знаем, что речь идет о гномах, так? Пусть каждый гном будет отдельным свойством JSON-объекта, где ключ — имя гнома. Например: Скорее всего, вы уже и сами можете представить, что нужно сделать, чтобы воплотить этот финальный штрих в жизнь. Но на всякий случай: 1. Добавляем сериализатор для всей компании гномов: 2. Убираем из сериализатора гнома (класс DwarfSerializer ) информацию об имени, удалив строку: 3. Регистрируем сериализатор отряда, добавив вызов метода registerTypeAdapter() класса GsonBuilder : Можно смело отправляться за синие горы, за белый туман! ОбратноВернувшись из JSON-приключения, отряд гномов, естественно, хочет преобразоваться обратно в уютные Java-объекты. Для обратного преобразования, то есть десериализации, у Gson есть метод fromJson() . Он принимает два параметра: данные в нескольких форматах (в т.ч. String , который мы и будем использовать) и тип возвращаемого результата. Однако, если мы попытаемся просто создать объект Gson и вызвать этот метод, как показано ниже, то получим экземпляр класса DwarvesBand с пустым списком гномов: Это естественно, ведь для преобразования мы использовали собственные алгоритмы, и настроенный по умолчанию Gson не знает, как обрабатывать наш формат. Поэтому, абсолютно аналогичным образом, мы должны создать специальные десериализаторы и указать библиотеке, что для обработки информации о гномах нужно использовать именно их. Как вы уже, возможно, догадались, для их создания нужно реализовать интерфейс JsonDeserializer и его единственный метод deserialize(). Принимаемые параметры:
Возвращаемый тип данных — параметризуется. Борррода!Начнем с малого. Восстановим данные о бороде и усах. Полный код десериализатора: Да, по-хорошему, стоило бы проверять входные данные более тщательно, но примем за данность, что они корректны, дабы не усложнять код примеров. Метод getAsString() преобразует содержимое JsonElement в строку, если применяется к элементу типа JsonPrimitive , содержащему валидную строку, или к JsonArray , содержащему только один такой элемент типа JsonPrimitive . В ином случае метод выбросит исключение. Аналогично работают все методы вида getAs Настало время восстановить данные о гноме. Делаем это так: Опять же, некоторые проверки опущены для лаконичности. Разберем по частям. Извлекаем возраст, используя сначала метод get() , который вернет нам JsonElement со значением указанного свойства «age», а затем метод getAsInt() , так как возраст имеет целочисленный тип. Восстанавливаем данные о бороде в объект типа FacialHair , используя context.deserialize() . Как мы помним, контекст осведомлен о том, что для обработки информации о бороде нужно использовать специальный десериализатор. Получаем значение свойства «weapons» сразу в виде Json-массива. Можно было бы сначала получить JsonElement методом get(«weapons»), затем проверить на принадлежность к типу массива методом isJsonArray() , и только затем преобразовать в массив с помощью метода getAsJsonArray() . Но мы верим в наших гномов и формат их входных данных. Осталось пройтись по массиву, восстанавливая данные об оружии: Для каждого элемента проверяем, относится ли он к типу JsonPrimitive . Мы помним, что обычное оружие описывается простой строкой, что соответствует данному типу. В таком случае создаем экземпляр обычного оружия, получая его тип методом getAsString() . В противном случае мы имеем дело с уникальным оружием. Мы обрабатывали его с помощью контекста, используя стандартные механизмы Gson. То же самое делаем и теперь, используя context.deserialize() . Заметили, что чего-то не хватает? И не просто «чего-то», а имени гнома! Чтобы завершить восстановление информации о гноме, добавив эту важную деталь, перейдем к последнему десериализатору. ОтрядНаконец, добавим обработчик для всего отряда гномов: Как и при обработке гнома, входные данные мы приводим к типу JsonObject . Помните, ранее упоминалось, что JsonObject можно воспринимать как Map ? По аналогии с Map , у JsonObject есть метод entrySet() , возвращающий множество элементов ключ-значение. Как раз с его помощью мы пройдем в цикле по всем записям о гномах. Оставшееся незаполненным имя содержится в ключе элемента. Записываем его в наш объект и — вуаля — информация о гноме полностью восстановлена! Home, sweet homeОсталось зарегистрировать наши свежеиспеченные десериализаторы, и можно начинать путешествие «Туда и Обратно». Регистрация абсолютно аналогична регистрации сериализаторов: Для проверки сначала преобразуем компанию гномов в Json-строку, затем обратно, и для наглядности выведем результат в виде Json-объекта, полученного с помощью стандартного механизма Gson. Можно убедиться, что никто не забыт и ничто не забыто, все гномы вернулись целые и невредимые! В обе стороныИтак, мы с вами рассмотрели путешествие «Туда» (из Java в JSON) и «Обратно» (из JSON в Java). Каждый раз в наших сериализаторах и десериализаторах мы работали с промежуточным слоем объектов типа JsonElement , которые любезно предоставлял нам Gson. Теперь мы, по старой схеме, должны уведомить Gson о новом обработчике для списка оружия, вызвав метод .registerTypeAdapter() . Однако, есть тут загвоздка. Первый параметр метода — это тип данных, для которого регистрируется обработчик, а оружие гнома у нас реализовано обычным списком: List . И мы явно не хотим, чтобы все другие списки обрабатывались нашим TypeAdapter’ом. Нужно как-то указать, что он предназначен только для списка оружия, передав параметризованный тип. Для этого в Gson используется специальный хитрый класс — TypeToken . С его помощью мы можем получить нужный нам параметризованный тип следующим образом: По сути, мы специально наследуем параметризованный класс TypeToken анонимным классом, чтобы затем методом getGenericSuperclass() получить параметризующий родителя тип. В нашем случае параметризующий родителя тип — это наш List . Несколько запутано, но по-другому, увы, никак. Более подробно про получение параметров Generic-классов можно почитать, например, в этой статье. Осталось только изменить код сериализации и десериализации гнома, передав управление по обработке оружия контексту с указанием типа обрабатываемого значения: Вот и все, адаптер подключен. Ах да, осталось еще реализовать его. Как обычно, под спойлером — полный код, который далее разберем подробнее по частям. И снова ТудаИтак, за преобразование «Туда» отвечает метод write() . Его код: Мы видим в параметрах метода экземпляр класса JsonWriter и наш список оружия. JsonWriter позволяет создавать выходной JSON в потоковом режиме. Для начала — нам нужен массив, где мы будем хранить данные об оружии. Эти команды, по сути, отвечают за расстановку квадратных скобок (как, собственно, и обозначаются массивы в JSON). Так как на выходе мы хотим получить массив, то в начале метода начинаем его, а в конце — заканчиваем. Тут все довольно просто. Аналогично используются методы value() : А для уникального оружия создаем объект и записываем в него две пары ключ-значения, вызывая поочередно методы name() и value() . Вот и всё, массив с оружием записан. И опять ОбратноМы довольно лихо преобразовали наше оружие в JSON-массив со смешанным типом данных, не так ли? И теперь настало время преобразовать его обратно. И тут нас ждет небольшая проблема. Итак, метод read() принимает один параметр: Класс JsonReader занимается извлечением данных из Json, и тоже в формате потока. Поэтому мы должны последовательно перебрать все «узлы», соответствующим образом их обработав. Мы знаем, что арсенал гнома представлен массивом, в котором содержатся объекты (для уникальных экземпляров) и строки (для обычных). Следовательно, обрабатывая каждый элемент массива, мы проверяем тип начального узла этого элемента. Для обработки строк и объектов у нас созданы методы, которые мы и вызываем. Прочие типы просто пропускаем методом skipValue() . Метод создания обычного оружия крайне прост: Просто получаем строку, в которой содержится тип оружия, методом nextString() и создаем на ее основе объект. С уникальным оружием — несколько сложнее: Мы заходим в объект и перебираем все его свойства с помощью метода nextName() . Для свойств с именами «name» и «type» у нас есть алгоритмы обработки — мы создаем на их основе экземпляры обычного и уникального оружия. Остальные свойства (буде таковые найдутся), опять же, пропускаем. Таким образом, десериализация арсенала гнома с помощью TypeAdapter готова. ПослесловиеВот и подошло к концу путешествие из Java в JSON и обратно. На этом позвольте откланяться, дорогой читатель. Надеюсь, вам было интересно. Источник |