GSON - это библиотека Java, используемая для реализации взаимного преобразования между объектами JSON и Java. GSON - это проект с открытым исходным кодом, размещенный по адресу https://github.com/google/gson.
Основным классом в GSON является GSON. Вы также можете использовать класс GsonBuilder, чтобы установить некоторые параметры при создании объектов GSON.
Объекты GSON не сохраняют какое -либо состояние при обработке JSON, поэтому пользователи могут легко выполнять множественную сериализацию, десериализацию и другие операции на одном и том же объекте GSON.
Пример: базовое использование
// serializationgson gson = new gson (); gson.tojson (1); // ==> Печать 1GSON.TOJSON ("ABCD"); // ==> Печать "abcd" gson.tojson (new long (10)); // ==> Печать 10int [] values = {1}; gson.tojson (values); // ==> Печать [1] // deserializationint one = gson.fromjson ("1", int.class); integer one = gson.fromjson ("1", integer.class); long one = gson.fromjson ("1", integer.class); long one = gson.fromjson ("1", long.class); gson.fromjson ("false", boolean.class); string str = gson.fromjson ("/" abc/"", string.class); string anotherstr = gson.fromjson ("[/" abc/"]", string.class); // serializationbagofprimitives obj = new Bagofprimitives (); // newarizationbrimitives obj = new Bagofprimitives (); // newarizationbagofprimitives = new Bagofprimives ();); gson.tojson (obj); // ==> json is {"value1": 1, "value2": "abc"}Пример: преобразование между объектом и JSON
Определите класс BagofPrimitives:
Class BagofPrimitives {private int value1 = 1; частная строка value2 = "abc"; частное переходное значение int3 = 3; BAGOFPrimitives () {// NO-Args Constructor}}Сериализован на JSON:
// serializationbagofprimitives obj = new BagofPrimitives (); Gson Gson = new Gson (); String json = gson.tojson (obj); // ==> json is {"value1": 1, "value2": "abc"}Не сериализуйте объекты, содержащие круглые ссылки, в противном случае возникнут бесконечная рекурсия.
Десериализация:
// deserializationbagofprimitives obj2 = gson.fromjson (json, bagofprimitives.class); // ==> obj2 - это как obj
Некоторые детали при обработке объектов:
Обработка вложенных классов (включая внутренние классы)
GSON может легко сериализовать вложенные классы и десериализовать статические вложенные классы. GSON не может автоматически десериализировать чистые внутренние классы, потому что не параметральный конструктор внутреннего класса должен ссылаться на объект, содержащий его (то есть экземпляры внешнего класса). Чтобы десериализировать статический класс, вы можете статически либо внутренний класс, либо предоставить пользовательского создателя экземпляра. Вот пример:
открытый класс A {public String a; класс B {public String b; public b () {// no args конструктор для b}}}Вышеуказанный класс B не может быть сериализован Gson. Поскольку класс B является (нестатическим) внутренним классом, GSON также не может десериализировать {"B": "ABC"} в экземпляр класса B. Если B объявляется статическим классом B, то GSON может десериализировать строку.
Другое решение - написать создателя экземпляра для B:
открытый класс InstanceCreatorForb реализует InstanceCreator <ab> {private final a a; public instancecreatorforb (a a) {this.a = a; } public ab createInstance (тип типа) {return a.new b (); }}Этот метод возможен, но не рекомендуется. (Переводчик сказал, что он не понимал создателя этого экземпляра и не знал, как его использовать)
Пример: массив
Gson gson = new gson (); int [] ints = {1, 2, 3, 4, 5}; string [] strings = {"abc", "def", "ghi"}; // serializationgson.tojson (ints); ==> Отпечатки [1,2,3,4,5] gson.tojson (строки); ==> Печать ["ABC", "def", "Ghi"] // deserializationint [] ints2 = gson.fromjson ("[1,2,3,4,5]", int []. Class); ==> INTS2 будет так же, как INTSGSON также поддерживает многомерные массивы со сложными типами данных.
Пример: коллекция
Gson Gson = new gson (); collection <Integer> ints = lists.imtablelist (1,2,3,4,5); // serializationString json = gson.tojson (ints); // ==> json IS [1,2,3,4,5] // deserializationtype collectiontype = new typetoken <collection <integer >> () {}. getType (); collection <Integer> ints2 = gson.fromjson (json, collectype); // ints2 - это то же самое, что и ints.Ограничения при обработке коллекций:
Serialize/Deserialize Generics
При использовании Tojson (OBJ) GSON называет obj.getClass (), чтобы получить информацию о поле для использования в сериализации. Точно так же объект myclass.class может быть передан в качестве параметра методу Fackjson (json, myclass.class), который можно использовать, когда объект не является общим. Однако, когда объект является общим объектом типа, информация об общем типе будет потеряна из -за механизма стирания типа в Java. Следующий пример иллюстрирует это:
класс foo <t> {t value;} gson gson = new gson (); foo <bar> foo = new foo <bar> (); gson.tojson (foo); // не может сериализовать foo.value правильно. // не удается десериализовать foo.value как барПриведенный выше код интерпретирует значение как тип панели, потому что GSON вызывает foo.getClass (), чтобы получить информацию класса, но этот метод возвращает примитивный класс, а именно Foo.class. Это означает, что GSON не может знать, что это объект типа Foo <Bar>.
Чтобы решить эту проблему, вы можете указать правильный параметризованный тип для ваших генериков. Вы можете использовать класс Typetoken для выполнения:
Type footype = new typetoken <foo <bar >> () {} .gettype (); gson.tojson (foo, footype); gson.fromjson (json, footype);FootyPe фактически определяет анонимный внутренний класс, который содержит метод getType (), который может вернуть все параметризованные типы.
Сериализовать/десериализовать набор объектов любого типа
Иногда обработанный JSON содержит смешанные типы, такие как:
['Hello', 5, {name: 'приветствия', источник: 'гость'}]Соответствующий набор должен быть:
Collection Collection = new ArrayList (); Collection.Add ("Hello"); Collection.Add (5); Collection.Add (новое событие («Приветствующие», "гость"));Класс событий определяется следующим образом:
Class Event {private String name; частный источник строки; частное событие (String name, String Source) {this.name = name; this.source = source; }}С GSON вам не нужно делать что -то особенное для сериализации коллекции: Tojson (Collection) вызовет удовлетворительные результаты.
Тем не менее, десериализация через Fromjson (json, collection.class) невозможна, потому что GSON не может соответствовать контенту в JSON с типом. Gson требует, чтобы вы предоставили общую версию типа коллекции в FromJson. У вас есть три варианта:
Решение 1: Используйте API анализатора GSON PARSER (анализатор потока низкого уровня или DOM PARSER JSONPARSER) для анализа элементов массива, а затем используйте gson.fromjson () для обработки каждого элемента массива. Это предпочтительное решение.
Схема 2: Зарегистрируйте адаптер типа для Collection.class для карты элементов в массиве соответствующему объекту. Недостатком этого метода является то, что он принесет неудобства при работе с другими типами сбора.
Схема 3: Зарегистрируйте адаптер типа для MyCollectionMemberType и используйте коллекцию <MyCollectionMemberType> в FromJson. Этот метод возможен только в том случае, если массив выглядит как элемент высокого уровня или если вы можете изменить тип поля на коллекцию <MyCollectionMemberType>.
Встроенный сериализатор/Deserializer
GSON предоставляет сериализатор/Deserializer для обычно используемых классов, которые могут не подходить для представления по умолчанию.
Вот список этих классов:
Пользовательская сериализация/десериализация
Иногда реализация GSON по умолчанию - это не то, что вы хотите, что чаще встречается при работе с некоторыми библиотеками классов (например, DateTime).
GSON позволяет вам зарегистрировать пользовательские сериализаторы/deserializers. Для этого вам нужно реализовать следующие части:
JSON Serializer: необходимо настроить сериализацию для объекта
JSON Deserializer: вам нужно настроить создателя класса Deserialization для типа: если есть конструктор без параметра или десериализатор, это не требуется.
Gsonbuilder gson = new gsonbuilder (); gson.registertypeadapter (mytype2.class, new mytypeadapter ()); gson.gerstertypeadapter (mytype.class, new Myserializ Mydeserializer ()); gson.registertypeadapter (mytype.class, new myinstancecreator ());
RegisterTyPeadApter проверяет, реализует ли тип адаптер несколько интерфейсов и регистрирует тип адаптера для этих интерфейсов.
Напишите сериализатор
Вот пример настройки сериализатора для DateTime:
Частный класс DateTimeSerializer реализует jsonserializer <DateTime> {public jsonElement serialize (dateTime src, type typeofsrc, jsonerializationcontext context) {return new jsonprimive (src.tostring ()); }}Gson вызывает tojson () при сериализации экземпляров DateTime.
Напишите десериализатор
В следующем примере показано, как написать десериализатор класса DateTime:
Частный класс DateTimedEserializer реализует JSondeserializer <DateTime> {public DateTime Deserialize (Jsonelement JSON, TypeOft, JSONDESerializationContext Context) Throws jsonParseException {return new DateTime (json.getAsjsonPrimity (). getAssTring ()); }}Когда GSON нужно покинуть строку JSON в объект DateTime, ForhJson () будет вызван.
Для сериализаторов/deseriaLizers следует обратить внимание на:
Напишите создатель экземпляра
При десериализации объекта GSON должен создать экземпляр класса. Класс, который хорошо работает во время сериализации/десериализации, означает, что этот класс имеет конструктор без параметра. Как правило, при работе с классами без параметров конструкторов в библиотеке классов требуется создатель экземпляра.
Пример создателя пример:
Частный класс MoneyInstanceCreator реализует InstanceCreator <Money> {Public Money CreateInstance (тип типа) {возвращать новые деньги ("1000000", currencyCode.usd); }}Создатель экземпляра параметризованного типа
Иногда тип, который будет создан, будет параметризованным типом. В целом, поскольку реальный экземпляр является примитивным типом, это не проблема. Вот пример:
Класс myList <t> extends arraylist <t> {} класс MyListInStanceCreator реализует InstanceCreator <mylist <? >> {@suppresswarnings ("unchecked") public mylist <?> CreateInstance (тип типа) {// Не нужно использовать список параметризованных, так как фактический экземпляр в любом случае будет иметь сырой. вернуть новый mylist (); }}Однако иногда вам нужно создавать экземпляры на основе реальных параметризованных типов. В этом случае вы можете передать параметр типа методу CreateInstance. Вот пример:
открытый идентификатор класса <t> {private final Class <t> classofid; Частная окончательная длинная стоимость; public id (class <t> classofid, long value) {this.classofid = classofid; this.value = значение; }} класс idinStanceCreator реализует instancecreator <id <? >> {public id <?> createInstance (type type) {type [] typeParameters = (((параметризованный тип) тип). GetActualtyPearguments (); Type idtype = typeparameters [0]; // ID имеет только один параметризованный тип t возвратный идентификатор. }}В приведенном выше примере экземпляр класса ID не может быть создан без передачи истинного типа параметризованному типу. Мы можем решить эту проблему, передав тип параметра методу. Здесь объект типа можно рассматривать как представление параметризованного типа Java ID <FOO>, а соответствующий экземпляр должен быть связан с ID <foo>. Поскольку идентификатор класса имеет только один параметр t параметра, мы используем GetActualtyPeargument () для возврата 0th -элемента массива типа, в этом примере Foo.class.
Компактный выход против красивого выхода
Вывод по умолчанию JSON в GSON находится в компактном формате JSON. То есть в JSON нет дополнительных персонажей пробелов. Следовательно, нет пустого места между именем поля и значением поля, между полями и между элементами массива в результате вывода JSON. Кроме того, нулевое поле не будет выводиться (примечание: NULL будет сохранен в объектах сбора и массива).
Если вы хотите вывести более красиво, вам нужно использовать GsonBuilder для настройки экземпляров GSON. JsonFormatter не существует в общедоступном API, поэтому клиент не может настроить настройки вывода по умолчанию. Теперь мы предоставляем только jsonprintformatter, который по умолчанию составляет 80 символов на строку, в отступление используется 2 символа, а правый край - 4 символа.
В следующем примере показано, как получить экземпляр GSON для использования jsonprintformatter вместо использования JSONCompactfortmatter по умолчанию.
Gson gson = new gsonbuilder (). SetPrettyPrinting (). Create (); String jsonOutput = gson.tojson (someObject);
Пустой объект
В реализации по умолчанию GSON облегчаются нулевые объекты. Это может сделать выходной формат (который может рассматриваться как результат сериализации) более плотным; Тем не менее, клиент должен определить значение по умолчанию для него, чтобы JSON мог нормализовать.
Если вы хотите сделать сериализуемый экземпляр GSON NULL, вы можете:
Gson Gson = new GsonBuilder (). Serializenulls (). Create ();
Обратите внимание, что при сериализации NULL элемент JSONNULL будет добавлен в структуру jsonElement. Поэтому мы можем использовать этот объект (GSON) в нашем пользовательском сериализаторе/Deserializer.
Вот пример:
открытый класс foo {private final String S; частный финал int i; public foo () {this (null, 5); } 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);Выход:
{"s": null, "i": 5} nullПоддержка версии
Вы можете использовать аннотацию @Since для поддержания нескольких версий одного и того же объекта. Эта аннотация может использоваться на классах и полях, а также будет поддерживаться методами в будущем. Чтобы использовать эту функцию, вам необходимо настроить экземпляр GSON, чтобы игнорировать поля и объекты, больше, чем определенный номер версии. Если версия не установлена в объекте GSON, все поля и классы используются при сериализации/десеризации.
public Class VersionedClass {@Since (1.1) Private Final String Newerfield; @Since (1.0) Private Final String Newfield; Приватное финальное поле строки; public versionedClass () {this.newerfield = "новая"; this.newfield = "new"; this.field = "old"; }} Versionedclass versionedObject = new VersionEdClass (); GSON GSON = NEW GSONBUILDER (). SETVersion (1.0) .Create (); String JSOUTPUT = GSON.TOJSON (SomeObject); System.out.println (jsonOutput); System.out.println (); gson = new gson (); gson.tojson (someobject); System.out.println (jsonOutput);Выход:
{"newfield": "new", "field": "old"} {"newerfield": "новый", "Newfield": "new", "Field": "Old"}Исключить поля из сериализации/десериализации
GSON поддерживает использование многих методов для удаления классов, полей и типов поля. Если следующий метод не соответствует вашим потребностям, вы можете использовать метод пользовательской сериализации/deserializer.
1. Исключение модификатора ява
По умолчанию, если поле объявляется переходным, поле исключено. Кроме того, если поле объявлено статическим, это поле также будет исключено по умолчанию. Если вы хотите включить некоторые поля, объявленные временными, вы можете сделать это:
Импорт java.lang.reflect.modifier; gson Gson = new GsonBuilder () .ExcludeFieldsWithModifiers (modifier.static) .create ();
Обратите внимание, что в методе ExcludeFieldsWithModifiers вы можете использовать как можно больше констант модификатора. Например:
Gson Gson = new GsonBuilder () .Excludefieldswithmodifiers (modifier.static, modifier.transient, modifier.volatile) .create ();
2. Используйте поле @Expose, чтобы исключить
Эта функция позволяет вам отмечать определенные поля в классе, чтобы они не были исключены/исключены в сериализации/десериализации. Чтобы использовать эту аннотацию, вы должны создать GSON, используя new GsonBuilder (). ExcludeFieldsWithoutexPoseAnnotation (). Create (). Экземпляр GSON будет исключать все поля в классе, которые не помечены @Expose.
3. Пользовательская политика исключения пользователя
Если вышеупомянутый метод исключения не может удовлетворить потребности, вы также можете настроить стратегию исключения. Для получения дополнительной информации, пожалуйста, обратитесь к ExclusionStrategy Javadoc.
В следующем примере показано, как исключить поля, помеченные @FOO, и исключить типы класса строк верхнего уровня или объявленные типы поля:
@RETENTION (armentPolicy.Runtime) @Target ({elementType.field}) public @Interface foo {// Полевой тег только аннотация} Общедоступный класс SampleObjectFortest {@foo Private Final int Annotatedfield; частная финальная строка Stringfield; Частный финальный длинное длинное месторождение; Частный финальный класс <?> Clazzfield; public samplebjectfortest () {annotatedfield = 5; stringfield = "onefaultValue"; Лонгфилд = 1234; }} открытый класс myExclusionStrategy реализует explusionStrategy {private final Class <?> typetoSkip; private myexclusionstrategy (класс <?> typetoskip) {this.typetoskip = typetoskip; } public boolean woodskipclass (class <?> clazz) {return (clazz == typetoskip); } public boolean weadskipfield (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); }Выход:
{"Лонгфилд": 1234}Поддержка именования на поле JSON
Некоторые предопределенные стратегии именования поля GSON могут преобразовать стандартные имена поля Java (то есть номенклатуру верблюда, такие как SampleFieldNameInjava) в имя поля JSON (то есть Sample_field_name_in_java или SamplefieldNameinjava). Для получения дополнительной информации, пожалуйста, обратитесь к FieldnamingPolicy.
GSON также имеет политику, основанную на аннотациях, позволяющая клиентам настраивать имена областей. В соответствии с этой стратегией, если нелегальное имя поля предоставляется в качестве аннотированного значения, GSON выпустит исключение времени выполнения.
В следующем примере показано, как использовать эти две стратегии именования GSON:
Частный класс SomeObject {@SerializedName ("custom_naming") частная конечная строка Somefield; частная финальная строка Someotherfield; public someobject (String a, String b) {this.somefield = a; это. }} SomeObject someObject = new -omeObject ("First", "Second"); gson Gson = new GsonBuilder (). SetFieldNamingPolicy (FieldnamingPolicy.upper_camel_case) .create (); String jsonRepresentation = gson.tojson (someobject);Выход:
{"custom_naming": "First", "Someotherfield": "Second"}Если вы хотите настроить имя, вы можете использовать аннотацию @SerializedName.
Состояние совместного использования между сериализатором и десериализатором
Иногда вам нужно поделиться состоянием между сериализатором и десериализатором, и вы можете использовать следующие три метода для достижения своей цели:
Первые два метода не безопасны для потока, третий-это.
Решение GSON SAINGING NULL Ошибка
Одним из недостатков GSON является то, что он не может установить нулевую замену.
Мы можем только вручную заменить нуль, возвращаемый сервером партиями. Когда нормальный интерфейс будет определен, сервер определенно не позволит возвращать NULL, но результат фона всегда будет выглядеть нулевым!
Если вы ищете, есть общий ответ,
Gson Gson = new GsonBuilder (). Serializenulls (). Create ();
Но это не может решить проблему снижения, как ее решить?
Решение заключается в следующем:
Gson gson = new gsonbuilder (). RegisterTyPeadApterFactory (new NullstringToemptyAdapterFactory ()). Create (); // затем используйте GSON, написанный в вышеупомянутой строке для сериализации и десериализации класса сущности. Nullstringtoemptyadapterfactory <t> реализует typeadapterfactory {@suppresswarnings ("unchecked") public <t> typeadapter <t> create (gson gson, typetoken <t> type) {class <t> rawtype = (class <t>) type.getrawtype (); if (rawtype! = string.class) {return null; } return (typeradapter <t>) new stringnulladapter (); }} // stringNullAdapter Code public Class stringNullAdapter extends tipeadapter <string> {@override public String Read (jsonreader Reader) Throws ioexception {// todo автоматически генерируется метод stub if (reader.peek () == jsontoken.null) {reader.nextnull (ufter.peek () == jsontoken.null) {reader.nextnull (); возвращаться ""; } return reader.nextString (); } @Override public void write (jsonwriter writer, строковое значение) Throws ioException {// todo автоматическое сгенерированное метод stub if (value == null) {writer.nullvalue (); возвращаться; } writer.value (value); }}