- Библиотека GSON
- Конвертируем объект в JSON
- Конвертируем JSON в объект
- Сложный класс
- Аннотации
- Пример для Kotlin
- Разбор JSON для Android с помощью Gson
- Почему Android не может найти com.google.gson.Gson
- Android com google gson
- Overview
- Goals for Gson
- Gson Performance and Scalability
- Gson Users
- Using Gson
- Primitives Examples
- Object Examples
- Finer Points with Objects
- Nested Classes (including Inner Classes)
- Array Examples
- Collections Examples
- Collections Limitations
- Serializing and Deserializing Generic Types
- Serializing and Deserializing Collection with Objects of Arbitrary Types
- Built-in Serializers and Deserializers
- Custom Serialization and Deserialization
- Writing a Serializer
- Writing a Deserializer
- Writing an Instance Creator
- InstanceCreator for a Parameterized Type
- Compact Vs. Pretty Printing for JSON Output Format
- Null Object Support
- Versioning Support
- Excluding Fields From Serialization and Deserialization
- Java Modifier Exclusion
- Gson’s @Expose
- User Defined Exclusion Strategies
- JSON Field Naming Support
Библиотека GSON
Библиотека GSON была разработана программистами Google и позволяет конвертировать объекты JSON в Java-объекты и наоборот.
Установим зависимость в Gradle.
Конвертируем объект в JSON
Создадим простейший класс Cat с открытыми полями.
Попробуем сконвертировать объект созданного класса в JSON при помощи метода toJson().
В логах видим строку:
Вот так просто можно превратить объект в строку. Это удобно при передаче данных, например, из приложения на сервер.
Перепишем пример немного иначе.
Смотрим на ответ. Теперь все данные данные выводятся по алфавиту.
Конвертируем JSON в объект
Естественно, нам нужно уметь выполнять и обратную задачу. Допустим с сервера пришёл ответ в виде JSON-строки и мы должны из неё построить объект для работы в своём приложении. В этом случае вызывается метод fromJson().
В этом примере нам пришлось экранировать кавычки. Но суть от этого не меняется. Получив строку, мы смогли создать объект murzik и узнать его имя, возраст, цвет.
Сложный класс
Класс Cat состоит из примитивных типов. Но иногда классы содержат объекты других классов. Усложним класс, добавив новый класс Address.
Посмотрим, что получится.
GSON справился с заданием и показал правильный результат (опять по алфавиту).
Пробуем в обратном порядке — из json-строки получим объект.
Аннотации
Можно использовать аннотации, чтобы помочь библиотеке разобраться с полями класса, если они не совпадают с нужным именем в json.
Мы не рассмотрели примеры, когда объект содержит массив/список элементов, отображения (Map), Set.
Пример для Kotlin
На данный момент использовать библиотеку GSON в Kotlin не рекомендуется, так как она не учитывает возможности языка при работе с null. Используйте альтернативы в виде библиотек Moshi, Jackson или специального плагина kotlinx.serialization.
Тем не менее приведу один пример. Для простоты создадим строку самостоятельно в формате JSON.
Создадим класс Cat на основе этого файла.
Строим объект через метод fromJson().
Источник
Разбор JSON для Android с помощью Gson
Помимо XML, JSON — очень распространенный формат, используемый в ответах API. Его простота помогла получить широкое распространение в пользу более многословного XML. Кроме того, JSON можно легко комбинировать с REST, создавая понятные и простые в использовании API. Android включает поддержку JSON в свой SDK, как кто-то может найти в сводке JSON-пакета . Однако, используя эти классы, разработчик должен иметь дело с низкоуровневым анализом JSON, который, на мой взгляд, утомителен и скучен. По этой причине в этом руководстве я собираюсь показать вам, как выполнять автоматический анализ JSON. Для этой цели мы будем использовать библиотеку Google Gson . С официального сайта:
Gson — это библиотека Java, которую можно использовать для преобразования объектов Java в их представление JSON. Его также можно использовать для преобразования строки JSON в эквивалентный объект Java. Gson может работать с произвольными объектами Java, включая уже существующие объекты, исходный код которых у вас отсутствует.
Есть несколько проектов с открытым исходным кодом, которые могут конвертировать объекты Java в JSON. Однако большинство из них требуют, чтобы вы размещали аннотации Java в своих классах, чего вы не можете сделать, если у вас нет доступа к исходному коду. Большинство также не полностью поддерживает использование Java Generics. Гсон считает, что оба они очень важные цели дизайна.
Отлично, именно то, что нам нужно. Прежде чем углубляться в код, вы можете взглянуть на Руководство пользователя Gson и добавить в закладки Javadocs API Gson . Давайте начнем с загрузки Gson , с текущей версией 1.6. Нам нужен gson-1.6.jar из дистрибутива.
Давайте приступим к созданию проекта Eclipse с именем «AndroidJsonProject» следующим образом:
Добавьте Gson JAR в classpath вашего проекта.
Чтобы проиллюстрировать, как использовать Gson для анализа JSON, мы собираемся проанализировать ответ JSON из API Twitter. Проверьте документацию по API Twitter для получения дополнительной информации. Мы собираемся использовать метод API поиска для выполнения специальных поисков.
Например, для поиска в Twitter о JavaCodeGeeks и получения результатов в формате JSON, вот соответствующий URL:
Источник
Почему Android не может найти com.google.gson.Gson
Я пытаюсь использовать GSON в своем проекте, но мое приложение терпит крах, и logcat говорит, что com.google.gson.Gson не может быть найден. Я поместил import com.google.gson.Gson в свои файлы классов, у меня есть gson в моем проводнике пакетов и добавил его по щелчку правой кнопкой мыши -> путь сборки -> добавить библиотеки. Он также отображается в Project-> properties-> java build path-> library tab-> gson. Что я сделал не так?
Что сработало для меня: установите флажок рядом с lib (gson-2.0.jar) в: «Свойства проекта» -> «Путь сборки Java» -> «Заказ и экспорт». Затем выполните очистку / сборку.
Это добавляет атрибут exported = true в элемент classpath
Вы помещали файл jar в папку libs проекта? Если нет, попробуйте переместить его там, создав папку, если потребуется. Должен быть на том же уровне, что и папка src.
У меня была аналогичная проблема, пытаясь создать приложение и его решить.
Я использую IntelliJ, а не eclipse, но вот как я это сделал:
Скопируйте их в папку «libs» вашего проекта. Я сделал это вручную, используя терминал, но вы можете сделать это, перейдя в папку проекта, расположенную на вашем компьютере. Ваше Project_Name> приложение> Libs [вставьте их здесь]
Перейдите в свой редактор (IntelliJ в моем случае). Вы должны увидеть следующие 3 файла в папке libs структуры проекта:
Откройте файл build.gradle и вставьте следующую строку в раздел зависимостей:
compile files(‘libs/gson-2.2.4.jar’, ‘libs/gson-2.2.4-javadoc.jar’, ‘libs/gson-2.2.4-javadoc.jar’)
Щелкните правой кнопкой мыши по каждому из исходных файлов и выберите «Добавить как библиотеку …»
Используйте следующие параметры:
- Name: name of the jar file
Level: Project Library
Перестроить проект Build > Rebuild project
Импорт и использование!
Сегодня я заметил, что вам не нравится, когда вы добавляете свою библиотеку. Решение, которое сработало для меня, заключалось в том, чтобы добавить его только в качестве внешней банки. Я наблюдал это, выполнив шаги, описанные автором этого сообщения, т. Е. Properties -> Java Build Path -> Libraries -> Добавить внешние JAR и указать на загруженную библиотеку gson.
Я столкнулся с той же проблемой (когда установлен SDK 17) …
Решение состоит в том, что вы просто помещаете чистые файлы jar в папку «libs» (без подпапок). Вам также не нужно объявлять их, android wil найдет их сами. Возможно, вам понадобится Project> Clean
Я уверен, что вы скопировали банку в «libs», а также добавили свойство> Java Build Path> (tab) Libraries, не так ли?
Мой вопрос был глупым … пожалуйста, проверьте, кроме Gson jar, если у вас есть две вещи, по крайней мере, на вкладке выше:
- Android xx
- Android Dependencies (особенно этот, я пропустил это, eclipse покажет мне ошибку «не удалось найти класс com.google.gson.xx»)
Просто сделайте копию проекта, решите эту проблему …
Не редактируйте файл .classpath напрямую или даже помещайте файлы в папки lib из Eclipse. Вместо этого используйте вкладку Java Build Path-> Order and Export, чтобы выбрать библиотеки, которые будут экспортированы в конечном подразделении развертывания (например, war / apk). Чтобы быть более безопасным, выполните Project-> Clean после изменения пути сборки.
У меня была схожая проблема, но я предполагаю, что мое требование было более сложным, так как libarary GSON использовался проектом Android Library, от которого зависел мой основной проект Android. Я пробовал оба подхода выше, но никто из них не работал для меня. Если я добавлю файл java GSON непосредственно в основной проект Android, он будет работать, но это не то, что я хотел.
С небольшим расследованием я понял, что банкомат GSON не использует никаких зависимостей (сторонних библиотек). Поэтому я решил скопировать исходный файл проекта GSON в src-файл проекта моего Android-библиотеки, и он работал как шарм. Поэтому вы можете использовать исходный код, а не двоичный код. Исходный код является частью загрузки в файле jar, просто разархивируйте его.
Я столкнулся с одним и тем же. Но решение было довольно простым, просто нажмите правой кнопкой мыши на свой проект -> «Правильности» -> «Библиотеки» -> Добавить внешние банки -> ОК, и это он. Он решил мою проблему. Надеюсь, он также решит вашу проблему
Если Projct Properties -> Java build path -> Добавить внешние банки не работают, и ваш проект является веб-проектом, попробуйте добавить gson jar непосредственно в папку lib сервера. Пример: для apache Tomcat для apache-tomcat / lib.
Я пробовал то же самое и читал так много ответов и пытался много чего, но не флаконе, но я решил эту проблему, выполнив всего один клик и простую.
1) Добавьте ваш .jar-файл в папку libs, убедитесь, что его libs not lib 2) Очистите и создайте проект, вы увидите этот файл в папке с папками 3) щелкните правой кнопкой мыши файл и перейдите к пути сборки и выберите команду add to build path
Запустите проект, он будет работать нормально. Надеюсь это поможет
Я использую Android Studio. У меня была та же самая проблема, с которой я справился, выбрав проект f4 из приложения popup click и в зависимостях выберите зависимость файла и выберите три папки, которые я вложил в каталог lib
Источник
Android com google gson
THIS PAGE HAS BEEN MOVED TO GITHUB:
Authors: Inderjeet Singh, Joel Leitch, Jesse Wilson
Overview
Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson is an open-source project hosted at http://code.google.com/p/google-gson.
Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
Goals for Gson
- Provide easy to use mechanisms like toString() and constructor (factory method) to convert Java to JSON and vice-versa
- Allow pre-existing unmodifiable objects to be converted to and from JSON
- Allow custom representations for objects
- Support arbitrarily complex object
- Generate compact and readability JSON output
Gson Performance and Scalability
Gson Users
Gson was originally created for use inside Google where it is currently used in a number of projects. It is now used by a number of public projects and companies. See details here.
Using Gson
The primary class to use is Gson which you can just create by calling new Gson(). There is also a class GsonBuilder available that can be used to create a Gson instance with various settings like version control and so on.
The Gson instance does not maintain any state while invoking Json operations. So, you are free to reuse the same object for multiple Json serialization and deserialization operations.
Primitives Examples
(Serialization)
Gson gson = new Gson();
gson .toJson(1); ==> prints 1
gson .toJson(«abcd»); ==> prints «abcd»
gson .toJson(new Long(10)); ==> prints 10
int[] values = < 1 >;
gson .toJson(values); ==> prints [1]
(Deserialization)
int one = gson .fromJson( «1», int.class);
Integer one = gson.fromJson(«1», Integer.class);
Long one = gson .fromJson( «1», Long.class);
Boolean false = gson .fromJson( «false», Boolean.class);
String str = gson .fromJson( «\»abc\»» , String.class);
String anotherStr = gson .fromJson( «[\»abc\»]» , String.class);
Object Examples
class BagOfPrimitives <
private int value1 = 1;
private String value2 = «abc»;
private transient int value3 = 3;
BagOfPrimitives() <
// no-args constructor
>
>
(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson ();
String json = gson.toJson(obj);
==> json is
Note that you can not serialize objects with circular references since that will result in infinite recursion .
(Deserialization)
BagOfPrimitives obj2 = gson .fromJson(json, BagOfPrimitives.class );
==> obj2 is just like obj
Finer Points with Objects
- It is perfectly fine (and recommended) to use private fields
- There is no need to use any annotations to indicate a field is to be included for serialization and deserialization. All fields in the current class (and from all super classes) are included by default.
- If a field is marked transient, (by default) it is ignored and not included in the JSON serialization or deserialization.
- This implementation handles nulls correctly
- While serialization, a null field is skipped from the output
- While deserialization, a missing entry in JSON results in setting the corresponding field in the object to null
- If a field is synthetic, it is ignored and not included in JSON serialization or deserialization
- Fields corresponding to the outer classes in inner classes, anonymous classes, and local classes are ignored and not included in serialization or deserialization
Nested Classes (including Inner Classes)
public class A <
public String a;
public String b;
public B() <
// No args constructor for B
>
>
>
NOTE: The above class B can not (by default) be serialized with Gson.
G s o n c a n n o t d e serialize <"b":"abc">into an instance of B since the class B is an inner class. if it was defined as static class B then Gson would have been able to deserialize the string. Another solution is to write a custom instance creator for B.
The above is possible, but not recommended.
Array Examples
(Serialization)
gson .toJson(ints); ==> prints [1,2,3,4,5]
gson .toJson(strings); ==> prints [«abc», «def», «ghi»]
(Deserialization)
int[] ints2 = gson .fromJson(«[1,2,3,4,5]», int[].class );
==> ints2 will be same as ints
We also support multi-dimensional arrays, with arbitrarily complex element types
Collections Examples
Gson gson = new G son ();
Collection ints = Lists.immutableList(1,2,3,4,5);
(Serialization)
String json = gson .toJson(ints); ==> json is [1,2,3,4,5]
(Deserialization)
Type collectionType = new TypeToken >()<>.getType();
Collection ints2 = gson .fromJson(json, collectionType);
ints2 is same as ints
Fairly hideous: note how we define the type of collection
Unfortunately, no way to get around this in Java
Collections Limitations
- Can serialize collection of arbitrary objects but can not deserialize from it
- Because there is no way for the user to indicate the type of the resulting object
- While deserializing, Collection must be of a specific generic type
All of this makes sense, and is rarely a problem when following good Java coding practices
Serializing and Deserializing Generic Types
When you call toJson(obj) , Gson calls obj.getClass() to get information on the fields to serialize. Similarly, you can typically pass MyClass.class object in the fromJson(json, MyClass.class) method. This works fine if the object is a non-generic type. However, if the object is of a generic type, then the Generic type information is lost because of Java Type Erasure. Here is an example illustrating the point:
Foo foo = new Foo ();
gson.toJson(foo); // May not serialize foo.value correctly
gson.fromJson(json, foo.getClass()); // Fails to deserialize foo.value as Bar
The above code fails to interpret value as type Bar because Gson invokes list.getClass() to get its class information, but this method returns a raw class, Foo.class . This means that Gson has no way of knowing that this is an object of type Foo , and not just plain Foo.
You can solve this problem by specifying the correct parameterized type for your generic type. You can do this by using the TypeToken class.
Type fooType = new TypeToken >() <>.getType();
gson.toJson(foo, fooType);
The idiom used to get fooType actually defines an anonymous local inner class containing a method getType() that returns the fully parameterized type.
Serializing and Deserializing Collection with Objects of Arbitrary Types
Built-in Serializers and Deserializers
Custom Serialization and Deserialization
Writing a Serializer
Here is an example of how to write a custom serializer for JodaTime DateTime class.
private class DateTimeSerializer implements JsonSerializer <
public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context) <
return new JsonPrimitive(src.toString());
>
>
Gson calls toJson() when it runs into a DateTime object during serialization.
Writing a Deserializer
Here is an example of how to write a custom deserializer for JodaTime DateTime class.
private class DateTimeDeserializer implements JsonDeserializer <
public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException <
return new DateTime(json.getAsJsonPrimitive().getAsString());
>
>
Gson calls fromJson() when it needs to deserialize a JSON string fragment into a DateTime object
Finer points with Serializers and Deserializers
Often you want to register a single handler for all generic types corresponding to a raw type
- For example, suppose you have an «Id» class for Id representation/translation (i.e. an internal vs. external representation).
- Id type that has same serialization for all generic types
- Essentially write out the id value
Deserialization is very similar but not exactly the same
- Need to call «new Id(Class , String)» which returns an instance of Id
Gson supports registering a single handler for this. You can also register a specific handler for a specific generic type (say Id needed special handling).
The Type parameter for the toJson and fromJson contains the generic type information to help you write a single handler for all generic types corresponding to the same raw type
Writing an Instance Creator
While deserializing an Object, Gson needs to create a default instance of the class
Well-behaved classes that are meant for serialization and deserialization should have a no-argument constructor
- Doesn’t matter whether public or private
Typically, Instance Creators are needed when you are dealing with a library class that does NOT define a no-argument constructor
Instance Creator Example
private class MoneyInstanceCreator implements InstanceCreator <
public Money createInstance(Type type) <
return new Money(«1000000», CurrencyCode.USD);
>
>
Type could be of a corresponding generic type
- Very useful to invoke constructors which need specific generic type information
- For example, if the Id class stores the class for which the Id is being created
InstanceCreator for a Parameterized Type
Sometimes that the type that you are trying to instantiate is a parameterized type. Generally, this is not a problem since the actual instance is of raw type. Here is an example:
class MyList extends ArrayList <
>
class MyListInstanceCreator implements InstanceCreator > <
@SuppressWarnings(«unchecked»)
public MyList createInstance(Type type) <
// No need to use a parameterized list since the actual instance will have the raw type anyway.
return new MyList();
>
>
However, sometimes you do need to create instance based on the actual parameterized type. In this case, you can use the type parameter being passed to the createInstance method. Here is an example:
public class Id <
private final Class classOfId;
private final long value;
public Id(Class classOfId, long value) <
this.classOfId = classOfId;
this.value = value;
>
>
class IdInstanceCreator implements InstanceCreator > <
public Id createInstance(Type type) <
Type[] typeParameters = ((ParameterizedType)type).getActualTypeArguments();
Type idType = typeParameters[0]; // Id has only one parameterized type T
return Id.get((Class)idType, 0L);
>
>
In the above example, an instance of the Id class can not be created without actually passing in the actual type for the parameterized type. We solve this problem by using the passed method parameter, type . The type object in this case is the Java parameterized type representation of Id where the actual instance should be bound to Id . Since Id class has just one parameterized type parameter, T , we use the zeroth element of the type array returned by getActualTypeArgument() which will hold Foo.class in this case.
Compact Vs. Pretty Printing for JSON Output Format
The default JSON output that is provide by Gson is a compact JSON format. This means that there will not be any whitespace in the output JSON structure. Therefore, there will be no whitespace between field names and its value, object fields, and objects within arrays in the JSON output. As well, «null» fields will be ignored in the output (NOTE: null values will still be included in collections/arrays of objects). See the Null Object Support section for information on configure Gson to output all null values.
If you like to use the Pretty Print feature, you must configure your Gson instance using the GsonBuilder . The JsonFormatter is not exposed through our public API, so the client is unable to configure the default print settings/margins for the JSON output. For now, we only provide a default JsonPrintFormatter that has default line length of 80 character, 2 character indentation, and 4 character right margin.
The following is an example shows how to configure a Gson instance to use the default JsonPrintFormatter instead of the JsonCompactFormatter :
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
Null Object Support
The default behaviour that is implemented in Gson is that null object fields are ignored. This allows for a more compact output format; however, the client must define a default value for these fields as the JSON format is converted back into its Java.
Here’s how you would configure a Gson instance to output null:
Gson gson = new GsonBuilder().serializeNulls().create();
NOTE: when serializing null s with Gson, it will add a JsonNull element to the JsonElement structure. Therefore, this object can be used in custom serialization/deserialization.
Here’s an example:
public class Foo <
private final String s;
private final int i;
public Foo(String s, int i) <
this.s = s;
this.i = i;
>
>
Gson gson = new GsonBuilder().serializeNulls().create();
Foo foo = new Foo();
String json = gson.toJson(foo);
System.out.println(json);
json = gson.toJson(null);
System.out.println(json);
Versioning Support
Multiple versions of the same object can be maintained by using @Since annotation. This annotation can be used on Classes, Fields and, in a future release, Methods. In order to leverage this feature, you must configure your Gson instance to ignore any field/object that is greater than some version number. If no version is set on the Gson instance then it will serialize and deserialize all fields and classes regardless of the version.
public class VersionedClass <
@Since(1.1) private final String newerField;
@Since(1.0) private final String newField;
private final String field;
public VersionedClass() <
this.newerField = «newer»;
this.newField = «new»;
this.field = «old»;
>
>
VersionedClass versionedObject = new VersionedClass();
Gson gson = new GsonBuilder().setVersion(1.0).create();
String jsonOutput = gson.toJson(someObject);
System.out.println(jsonOutput);
System.out.println();
Excluding Fields From Serialization and Deserialization
Gson supports numerous mechanisms for excluding top-level classes, fields and field types. Below are pluggable mechanism that allow field and class exclusion. If none of the below mechanism satisfy your needs then you can always use custom serializers and deserializers.
Java Modifier Exclusion
By default, if you mark a field as transient , it will be excluded. As well, if a field is marked as «static» then by default it will be excluded. If you want to include some transient fields then you can do the following:
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC)
.create();
NOTE: you can use any number of the Modifier constants to » excludeFieldsWithModifiers » method. For example:
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
.create();
Gson’s @Expose
User Defined Exclusion Strategies
If the above mechanisms for excluding fields and class type do not work for you then you can always write your own exclusion strategy and plug it into Gson. See the ExclusionStrategy JavaDoc for more information.
The following example shows how to exclude fields marked with a specific «@Foo» annotation and excludes top-level types (or declared field type) of class String.
@Retention(RetentionPolicy.RUNTIME)
@Target(
public @interface Foo <
// Field tag only annotation
>
public class SampleObjectForTest <
@Foo private final int annotatedField;
private final String stringField;
private final long longField;
private final Class clazzField;
public SampleObjectForTest() <
annotatedField = 5;
stringField = «someDefaultValue»;
longField = 1234;
>
>
public class MyExclusionStrategy implements ExclusionStrategy <
private final Class typeToSkip;
private MyExclusionStrategy(Class typeToSkip) <
this.typeToSkip = typeToSkip;
>
public boolean shouldSkipClass(Class clazz) <
return (clazz == typeToSkip);
>
public boolean shouldSkipField(FieldAttributes f) <
return f.getAnnotation(Foo.class) != null;
>
>
public static void main(String[] args) <
Gson gson = new GsonBuilder()
.setExclusionStrategies(new MyExclusionStrategy(String.class))
.serializeNulls()
.create();
SampleObjectForTest src = new SampleObjectForTest();
String json = gson.toJson(src);
System.out.println(json);
>
JSON Field Naming Support
Gson supports some pre-defined field naming policies to convert the standard Java field names (i.e. camel cased names starting with lower case — «sampleFieldNameInJava») to a Json field name (i.e. sample_field_name_in_java or SampleFieldNameInJava). See the FieldNamingPolicy class for information on the pre-defined naming policies.
It also has an annotation based strategy to allows clients to define custom names on a per field basis. Note, that the annotation based strategy has field name validation which will raise «Runtime» exceptions if an invalid field name is provided as the annotation value.
The following is an example of how to use both Gson naming policy features:
private class SomeObject <
@SerializedName(«custom_naming») private final String someField;
private final String someOtherField;
Источник