Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Библиотека GSON была разработана программистами Google и позволяет конвертировать объекты JSON в Java-объекты и наоборот.
Домашняя страница: Гитхаб
Установим зависимость в Gradle.
implementation 'com.google.code.gson:gson:2.8.5'
Создадим простейший класс Cat с открытыми полями.
package ru.alexanderklimov.gsondemo;
public class Cat {
public String name; // имя
public int age; // возраст
public int color; // цвет
// Конструктор
public Cat(){
}
}
Попробуем сконвертировать объект созданного класса в JSON при помощи метода toJson().
Cat murzik = new Cat();
murzik.name = "Мурзик";
murzik.age = 9;
murzik.color = Color.BLACK;
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
Log.i("GSON", gson.toJson(murzik));
В логах видим строку:
{"name":"Мурзик","color":-16777216,"age":9}
Вот так просто можно превратить объект в строку. Это удобно при передаче данных, например, из приложения на сервер.
Перепишем пример немного иначе.
Cat barsik = new Cat();
barsik.name = "Барсик";
barsik.age = 8;
Gson gson = new Gson();
Log.i("GSON", gson.toJson(barsik));
Смотрим на ответ. Теперь все данные данные выводятся по алфавиту.
{"age":8,"color":0,"name":"Барсик"}
Естественно, нам нужно уметь выполнять и обратную задачу. Допустим с сервера пришёл ответ в виде JSON-строки и мы должны из неё построить объект для работы в своём приложении. В этом случае вызывается метод fromJson().
String jsonText = "{\"name\":\"Мурзик\",\"color\":-16777216,\"age\":9}";
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
Cat murzik = gson.fromJson(jsonText, Cat.class);
Log.i("GSON", "Имя: " + murzik.name + "\nВозраст: " + murzik.age);
В этом примере нам пришлось экранировать кавычки. Но суть от этого не меняется. Получив строку, мы смогли создать объект murzik и узнать его имя, возраст, цвет.
String jsonText = "{'name':'Мурзик','color':-16777216,'age':8}";
Класс Cat состоит из примитивных типов. Но иногда классы содержат объекты других классов. Усложним класс, добавив новый класс Address.
// Cat.java
package ru.alexanderklimov.gsondemo;
public class Cat {
public String name; // имя
public int age; // возраст
public int color; // цвет
public Address address;
public Cat(){
}
}
// Address.java
package ru.alexanderklimov.gsondemo;
public class Address {
String street;
String city;
String country;
public Address(String street, String city, String country){
this.street = street;
this.city = city;
this.country = country;
}
}
Посмотрим, что получится.
Cat murzik = new Cat();
murzik.name = "Мурзик";
murzik.age = 9;
murzik.color = Color.BLACK;
murzik.address = new Address("Arbat", "Moscow", "Russia");
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
Log.i("GSON", gson.toJson(murzik));
// {"address":{"city":"Moscow","country":"Russia","street":"Arbat"},"age":9,"color":-16777216,"name":"Мурзик"}
GSON справился с заданием и показал правильный результат (опять по алфавиту).
Пробуем в обратном порядке - из json-строки получим объект.
String jsonText = "{\"address\":{\"city\":\"New York\",\"country\":\"USA\"," +
"\"street\":\"Wall Street\"},\"age\":11,\"color\":-16777216,\"name\":\"Murzik\"}";
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
Cat murzik = gson.fromJson(jsonText, Cat.class);
Log.i("GSON", "Имя: " + murzik.name + "\nВозраст: " + murzik.age + "\nCity: " + murzik
.address.city);
// GSON: Имя: Murzik
// Возраст: 11
// City: New York
Тоже работает.
Можно использовать аннотации, чтобы помочь библиотеке разобраться с полями класса, если они не совпадают с нужным именем в json.
@SerializedName("Id")
public long id;
Мы не рассмотрели примеры, когда объект содержит массив/список элементов, отображения (Map), Set.
На данный момент использовать библиотеку GSON в Kotlin не рекомендуется, так как она не учитывает возможности языка при работе с null. Используйте альтернативы в виде библиотек Moshi, Jackson или специального плагина kotlinx.serialization.
Тем не менее приведу один пример. Для простоты создадим строку самостоятельно в формате JSON.
val jsonStr = """
{
"name": "Barsik",
"age": 21,
"isAwesome": true
}
""".trimIndent()
Создадим класс Cat на основе этого файла.
data class Cat(val name: String, val age: Int, val isAwesome: Boolean)
Строим объект через метод fromJson().
val jsonStr = """
{
"name": "Barsik",
"age": 21,
"isAwesome": true
}
""".trimIndent()
val cat: Cat = Gson().fromJson<Cat>(jsonStr, Cat::class.java)
println(cat)