Мы продолжаем использовать 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 (), как показано в следующей серии листинга.
010203040506070809101112131415class
Developer {
private
String name;
private
String classz;
List<String> languagesKnown;
public
Developer() {
name =
"ajduke"
;
classz=
"Developer"
;
languagesKnown =
new
ArrayList<>();
languagesKnown.add(
"Java"
);
languagesKnown.add(
"Scala"
);
languagesKnown.add(
"Ruby"
);
}
}
Для этого примера мы не включаем приватные поля. Хотя вы можете исключить поля с любыми модификаторами (любые модификаторы, которые применяются к полям)
01020304050607080910111213141516Gson gson =
new
Gson();
System.out.println(
"Default behaviour "
);
GsonBuilder gsonBuilder =
new
GsonBuilder();
Gson prettyGson = gsonBuilder.setPrettyPrinting().create();
String json = prettyGson.toJson(
new
Developer());
System.out.println(json);
System.out.println(
"Ignoring/excluding fields "
);
GsonBuilder excludeFieldsWithModifiers = gsonBuilder
.excludeFieldsWithModifiers(Modifier.PRIVATE);
Gson create = excludeFieldsWithModifiers.create();
String json2 = create.toJson(
new
Developer());
System.out.println(json2);
В следующем выводе вы можете увидеть, что закрытые поля исключены согласно нашей программе, хотя вы можете игнорировать поля, которые могут быть защищены, синхронизированы и т. Д.
01020304050607080910111213141516171819Default behaviour
{
"name"
:
"ajduke"
,
"classz"
:
"Developer"
,
"languagesKnown"
: [
"Java"
,
"Scala"
,
"Ruby"
]
}
Ignoring
/excluding
fields
{
"languagesKnown"
: [
"Java"
,
"Scala"
,
"Ruby"
]
}
- Использование аннотации Expose
Gson также предоставляет аннотацию, которую можно пометить для полей, поэтому эти поля будут исключены из сериализованного вывода.
Для использования этого нам нужно следующие два
- настроить экземпляр gson следующим образом
Gson gson = GsonBuilder (). ExcludeFieldsWithoutExposeAnnotation (). Create () - и пометьте поля аннотациями @Expose, которые должны быть включены в окончательный вывод json. Таким образом, тот, который не отмечен, будет исключен
Следующий список показывает подробное использование
010203040506070809101112131415class
Developer {
// this field will be included
@Expose
private
String name;
private
String classz;
List<String> languagesKnown;
public
Developer() {
name =
"ajduke"
;
languagesKnown =
new
ArrayList<>();
languagesKnown.add(
"Java"
);
languagesKnown.add(
"Scala"
);
languagesKnown.add(
"Ruby"
);
}
}
1234567public
class
GsonEx {
public
static
void
main(String[] args)
throws
IOException {
Gson gson =
new
GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(
new
Developer());
System.out.println(json);
}
}
Выход следующим образом:
1{
"name"
:
"ajduke"
}
- настроить экземпляр gson следующим образом
- Определяемая пользователем стратегия исключения
Библиотека Google Gson обеспечивает очень детальный уровень исключений полей в зависимости от типа поля и атрибутов поля.
Для этого вам необходимо реализовать интерфейс ExclusionStrategy, реализовав два его метода, таких как shouldSkipClass () и shouldSkipField () . Прежний может быть реализован так, что он будет пропускать поля в зависимости от его типа, а позже может быть реализован на основе атрибута поля, такого как его модификатор, его аннотация и т. Д.
и теперь, после реализации интерфейса ExclusionStrategy, вам нужно передать его в метод GsonBuilder # setExclusionStrategies () для настройки экземпляра gson.
Ниже приведена минимальная реализация стратегии исключения, в которой мы исключаем, что поля имеют тип String, List, а также поле с аннотацией как устаревшей.
Обратите внимание на следующую реализацию ExclusionStrategy
0102030405060708091011121314151617class
ExclusionStrategyImpl
implements
ExclusionStrategy {
private
final
Class<?> classTypeToSkip;
public
ExclusionStrategyImpl(Class<?> classTypeToSkip) {
this
.classTypeToSkip = classTypeToSkip;
}
@Override
public
boolean
shouldSkipClass(Class<?> claz) {
return
classTypeToSkip == claz;
}
@Override
public
boolean
shouldSkipField(FieldAttributes fa) {
return
fa.getAnnotation(Deprecated.
class
) !=
null
;
}
}
Наш пользовательский класс Developer для показа примера:
01020304050607080910111213141516class
Developer {
@Deprecated
private
int
count =
45
;
private
String name;
private
String classz;
List<String> languagesKnown;
public
Developer() {
name =
"ajduke"
;
classz = Developer.
class
.getCanonicalName();
languagesKnown =
new
ArrayList<>();
languagesKnown.add(
"Java"
);
languagesKnown.add(
"Scala"
);
languagesKnown.add(
"Ruby"
);
}
}
0102030405060708091011121314151617181920212223242526public
class
Ex35 {
public
static
void
main(String[] args) {
Gson gson =
null
;
Developer developer =
new
Developer();
String json =
null
;
gson =
new
Gson();
json = gson.toJson(developer);
System.out.println(
"Default behaviuor...."
);
System.out.println(json);
// exclude field having String
gson =
new
GsonBuilder().setExclusionStrategies(
new
ExclusionStrategyImpl(List.
class
)).create();
json = gson.toJson(developer);
System.out.println(
"\nExclude fields with type - List"
);
System.out.println(json);
// exclude field having List
gson =
new
GsonBuilder().setExclusionStrategies(
new
ExclusionStrategyImpl(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 with
type
- List
{
"name"
:
"ajduke"
,
"classz"
:
"in.ajduke.ap013.Developer"
}
Exclude fields with
type
- 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" } |