GSON - 打印所有注释为deserialized = true的字段

时间:2018-02-20 13:48:02

标签: java json gson

我有一个 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对象,这些对象将用作我的应用程序的输入,因此我不必手动输入它。

1 个答案:

答案 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
  • 默认情况下,Gson不会使用null值序列化文件,因此您需要使用构建器方法.serializeNulls()。这不会生成字符串值为""的Json,而只生成null
  • 在您的示例中,Json字段包含空字符串作为值,但您没有引入默认构造函数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;
    }
}
相关问题