Мы продолжаем использовать GSON из предыдущей статьи , также в случае, если вы пропустили первую статью в серии, перейдите по ссылке . Итак, здесь мы идем с другим взносом в серии.
Поддержка версий
Если вы хотите сохранить несколько версий объекта для преобразования JSON, в библиотеке Google GSON есть хорошая аннотация @Since. Эта аннотация может применяться к полям и классам.
Например, предположим, что вы поддерживаете несколько версий REST API и используете JSON в качестве полезной нагрузки конечного ответа. На следующей итерации вашего API вы добавляете некоторые поля для конкретной сущности JSON и не хотите отправлять вновь добавленные поля в предыдущую версию API, после чего появляется аннотация @Since. Давайте посмотрим в следующем листинге, как мы используем эту функцию.
Чтобы использовать эту аннотацию, вы, конечно, должны сконфигурировать экземпляр Gson для конкретной версии, используя GsonBuilder.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class Example33 { public static void main(String[] args) { Gson gson = new GsonBuilder().setVersion(2.0).create(); String json = gson.toJson(new ExampleClass()); System.out.println("Output for version 2.0..."); System.out.println(json); gson= new GsonBuilder().setVersion(1.0).create(); json = gson.toJson(new ExampleClass()); System.out.println("\nOutput for version 1.0..."); System.out.println(json); gson= new Gson(); json = gson.toJson(new ExampleClass()); System.out.println("\nOutput for No version set..."); System.out.println(json); }}class ExampleClass{ String field= "field"; // this is in version 1.0 @Since(1.0) String newField1 = "field 1"; // following will be included in the version 1.1 @Since(2.0) String newField2 = "field 2";} |
Выход выше как:
|
1
2
3
4
5
6
7
8
|
Output for version 2.0...{"field":"field","newField1":"field 1","newField2":"field 2"}Output for version 1.0...{"field":"field","newField1":"field 1"}Output for No version set...{"field":"field","newField1":"field 1","newField2":"field 2"} |
Если вы не указали какую-либо версию, она будет включать все поля независимо от ее версии.
Отключить экранирование HTML
По умолчанию во время преобразования все содержащиеся html-символы будут преобразованы в соответствующий им Unicode, т.е. < to \ u003c, > в \ u003e, & to \ u0026e и т. Д.
Чтобы передать html-символы как есть, вам нужно настроить экземпляр gson на использование метода GsonBuilder # disableHtmlEscaping () .
Следующий листинг показывает использование:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
public class Example34 { public static void main(String[] args) { String str ="<myval>"; Gson gson = new Gson(); System.out.println("Normal behaviour..."); System.out.println(gson.toJson(str)); System.out.println("\nDisabled html escaping..."); gson = new GsonBuilder().disableHtmlEscaping().create(); System.out.println(gson.toJson(str)); }} |
Вывести следующим образом:
|
1
2
3
4
5
|
Normal behaviour..."\u003cmyval\u003e"Disabled html escaping..."<myval>" |
Исключить поля из вывода Json
Для этого у Google GSON есть 4 способа
- поля с переходным и статическим модификатором
- исключить с полями с определенными модификаторами
- Использование аннотации Expose
- Определяемые пользователем стратегии исключения
Давайте рассмотрим каждый из них подробно:
- поля с переходным и статическим модификатором
Это поведение по умолчанию, при котором вы изменяете поле с помощью временного модификатора, оно не будет включено, как мы видели в первой статье серии, и, конечно, поле со статическим модификатором также исключается, поскольку оно является частью класса, а не экземпляра.
- исключить поля с определенными модификаторами
Вы можете настроить экземпляр gson так, чтобы он исключал поля с указанными вами модификаторами, например, вы можете исключать / игнорировать поля с защищенным или закрытым модификатором.
Чтобы использовать это, вам нужно использовать GsonBuilder # excludeFieldsWithModifiers (), как показано в следующей серии листинга.
010203040506070809101112131415classDeveloper {privateString name;privateString classz;List<String> languagesKnown;publicDeveloper() {name ="ajduke";classz="Developer";languagesKnown =newArrayList<>();languagesKnown.add("Java");languagesKnown.add("Scala");languagesKnown.add("Ruby");}}Для этого примера мы не включаем приватные поля. Хотя вы можете исключить поля с любыми модификаторами (любые модификаторы, которые применяются к полям)
01020304050607080910111213141516Gson gson =newGson();System.out.println("Default behaviour ");GsonBuilder gsonBuilder =newGsonBuilder();Gson prettyGson = gsonBuilder.setPrettyPrinting().create();String json = prettyGson.toJson(newDeveloper());System.out.println(json);System.out.println("Ignoring/excluding fields ");GsonBuilder excludeFieldsWithModifiers = gsonBuilder.excludeFieldsWithModifiers(Modifier.PRIVATE);Gson create = excludeFieldsWithModifiers.create();String json2 = create.toJson(newDeveloper());System.out.println(json2);В следующем выводе вы можете увидеть, что закрытые поля исключены согласно нашей программе, хотя вы можете игнорировать поля, которые могут быть защищены, синхронизированы и т. Д.
01020304050607080910111213141516171819Default behaviour{"name":"ajduke","classz":"Developer","languagesKnown": ["Java","Scala","Ruby"]}Ignoring/excludingfields{"languagesKnown": ["Java","Scala","Ruby"]} - Использование аннотации Expose
Gson также предоставляет аннотацию, которую можно пометить для полей, поэтому эти поля будут исключены из сериализованного вывода.
Для использования этого нам нужно следующие два
- настроить экземпляр gson следующим образом
Gson gson = GsonBuilder (). ExcludeFieldsWithoutExposeAnnotation (). Create () - и пометьте поля аннотациями @Expose, которые должны быть включены в окончательный вывод json. Таким образом, тот, который не отмечен, будет исключен
Следующий список показывает подробное использование
010203040506070809101112131415classDeveloper {// this field will be included@ExposeprivateString name;privateString classz;List<String> languagesKnown;publicDeveloper() {name ="ajduke";languagesKnown =newArrayList<>();languagesKnown.add("Java");languagesKnown.add("Scala");languagesKnown.add("Ruby");}}1234567publicclassGsonEx {publicstaticvoidmain(String[] args)throwsIOException {Gson gson =newGsonBuilder().excludeFieldsWithoutExposeAnnotation().create();String json = gson.toJson(newDeveloper());System.out.println(json);}}Выход следующим образом:
1{"name":"ajduke"} - настроить экземпляр gson следующим образом
- Определяемая пользователем стратегия исключения
Библиотека Google Gson обеспечивает очень детальный уровень исключений полей в зависимости от типа поля и атрибутов поля.
Для этого вам необходимо реализовать интерфейс ExclusionStrategy, реализовав два его метода, таких как shouldSkipClass () и shouldSkipField () . Прежний может быть реализован так, что он будет пропускать поля в зависимости от его типа, а позже может быть реализован на основе атрибута поля, такого как его модификатор, его аннотация и т. Д.
и теперь, после реализации интерфейса ExclusionStrategy, вам нужно передать его в метод GsonBuilder # setExclusionStrategies () для настройки экземпляра gson.
Ниже приведена минимальная реализация стратегии исключения, в которой мы исключаем, что поля имеют тип String, List, а также поле с аннотацией как устаревшей.
Обратите внимание на следующую реализацию ExclusionStrategy
0102030405060708091011121314151617classExclusionStrategyImplimplementsExclusionStrategy {privatefinalClass<?> classTypeToSkip;publicExclusionStrategyImpl(Class<?> classTypeToSkip) {this.classTypeToSkip = classTypeToSkip;}@OverridepublicbooleanshouldSkipClass(Class<?> claz) {returnclassTypeToSkip == claz;}@OverridepublicbooleanshouldSkipField(FieldAttributes fa) {returnfa.getAnnotation(Deprecated.class) !=null;}}Наш пользовательский класс Developer для показа примера:
01020304050607080910111213141516classDeveloper {@Deprecatedprivateintcount =45;privateString name;privateString classz;List<String> languagesKnown;publicDeveloper() {name ="ajduke";classz = Developer.class.getCanonicalName();languagesKnown =newArrayList<>();languagesKnown.add("Java");languagesKnown.add("Scala");languagesKnown.add("Ruby");}}0102030405060708091011121314151617181920212223242526publicclassEx35 {publicstaticvoidmain(String[] args) {Gson gson =null;Developer developer =newDeveloper();String json =null;gson =newGson();json = gson.toJson(developer);System.out.println("Default behaviuor....");System.out.println(json);// exclude field having Stringgson =newGsonBuilder().setExclusionStrategies(newExclusionStrategyImpl(List.class)).create();json = gson.toJson(developer);System.out.println("\nExclude fields with type - List");System.out.println(json);// exclude field having Listgson =newGsonBuilder().setExclusionStrategies(newExclusionStrategyImpl(String.class)).create();json = gson.toJson(developer);System.out.println("\nExclude fields with type - String");System.out.println(json);}}Выход выше, как следует:
12345678Default behaviuor....{"count":45,"name":"ajduke","classz":"in.ajduke.ap013.Developer","languagesKnown":["Java","Scala","Ruby"]}Exclude fields withtype- List{"name":"ajduke","classz":"in.ajduke.ap013.Developer"}Exclude fields withtype- String{"languagesKnown":[null,null,null]}
Именование пользовательских полей с использованием политики именования полей
Как мы видели в прошлой статье, Gson по умолчанию включает имя выходного поля json, такое же, как имя поля класса, а также мы можем переопределить это с помощью аннотации @serilizedName.
В Gson есть еще кое-что, что позволяет определить имя поля json, которое будет изменено на прописные, строчные и т. Д. Без использования каких-либо комментариев.
Для этого вам нужно использовать метод GsonBuilder (). SetFieldNamingPolicy () и передать соответствующий FieldNamePolicy.
Следующий листинг показывает использование:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package in.ajduke.ap013;import com.google.gson.FieldNamingPolicy;import com.google.gson.Gson;import com.google.gson.GsonBuilder;public class Example34 { public static void main(String[] args) { Gson gson = new Gson(); String json = gson.toJson(new JsonClass()); System.out.println("Default behaviour...."); System.out.println(json); gson = new GsonBuilder().setFieldNamingPolicy( FieldNamingPolicy.LOWER_CASE_WITH_DASHES).create(); json = gson.toJson(new JsonClass()); System.out.println("\nFields with lower case with dashes..."); System.out.println(json); gson = new GsonBuilder().setFieldNamingPolicy( FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES).create(); json = gson.toJson(new JsonClass()); System.out.println("\nFields with upper case with spaces..."); System.out.println(json); }}class JsonClass { String myField = "value1"; String myAnotherField = "value2";} |
|
1
2
3
4
5
6
7
8
|
Default behaviour....{"myField":"value1","myAnotherField":"value2"}Fields with lower case and dashes...{"my-field":"value1","my-another-field":"value2"}Fields with lower case and dashes...{"My Field":"value1","My Another Field":"value2"} |