我有一个 Java EE 项目正在使用 GSON 库(Google的库来处理JSON对象)。
在我的实体类中,我使用@Expose
注释来控制GSON考虑哪些字段。我还在该批注上使用 serialize / deserialize 属性来控制在将Java对象序列化为JSON时考虑哪些字段,以及在将JSON对象反序列化为Java对象时考虑哪些字段。例如:
public class Movie {
@Expose(serialize=true, deserialize=false)
@Id
@GeneratedValue
private long id;
@Expose(serialize=true, deserialize=true)
private String name;
@Expose(serialize=true, deserialize=true)
private String genre;
@Expose(serialize=false, deserialize=true)
private String secretID;
}
当我将JSON对象发送到反序列化到Java对象时,我发送一个这样的对象:
{
"name": "Memento",
"genre": "thriller",
"secretID": "123asd"
}
而且,当我序列化 Java对象到JSON时,我会得到这样的结果:
{
"id": 1,
"name": "Memento",
"genre": "thriller"
}
我有这个Java代码:
public static void main(String[] args) {
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create();
String json = gson.toJson(new Movie());
System.out.println(json);
}
生成它作为它的输出:
{
"id": 0,
"name": "",
"genre": ""
}
这些是标记为序列化的字段。但是,如果我需要打印出所有标记为反序列化的字段,以便我可以更轻松地创建一个JSON对象,该对象将在创建新电影时用作输入。
所需的输出是:
{
"name": "",
"genre": "",
"secretID": ""
}
注意:我不想更改@Expose
注释的序列化/反序列化属性,因为它们设置为我的应用程序需要工作的方式。我只需要一种简单的方法来生成模板JSON对象,这些对象将用作我的应用程序的输入,因此我不必手动输入它。
答案 0 :(得分:0)
您可以实现更通用的ExclusionStrategy
,例如:
@RequiredArgsConstructor
public class IncludeListedFields implements ExclusionStrategy {
@NonNull
private Set<String> fieldsToInclude;
@Override
public boolean shouldSkipField(FieldAttributes f) {
return ! fieldsToInclude.contains(f.getName());
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
}
然后使用它:
Set<String> fieldsToInclude =
new HashSet<>(Arrays.asList("name", "genre", "secretID"));
ExclusionStrategy es = new IncludeListedFields(fieldsToInclude);
Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls()
.addSerializationExclusionStrategy(es).create();
请注意以下事项:
.excludeFieldsWithoutExposeAnnotation
。null
值序列化文件,因此您需要使用构建器方法.serializeNulls()
。这不会生成字符串值为""
的Json,而只生成null
。Movie()
,它会将字段值初始化为空字符串,因此它们保持为null
。但是如果你初始化它们 - 比如说空字符串""
- 那么它们就不是空的&amp;您不需要使用构建器方法.serializeNulls()
。 但是如果您真的需要并且只想根据@Expose(deserialize=true)
进行序列化,那么ExclusionStrategy
可以只是:
public class PrintDeserializeTrue implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes f) {
Expose annotationExpose = f.getAnnotation(Expose.class);
if(null != annotationExpose) {
if(annotationExpose.deserialize())
return false;
}
return true;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
}