【问题标题】:GSON - print all fields that are annotated as deserialized=trueGSON - 打印所有注释为反序列化 = true 的字段
【发布时间】:2018-02-20 13:48:01
【问题描述】:

我有一个 Java EE 项目正在使用 GSON 库(Google 用于处理 JSON 对象的库)。

在我的 entity 类中,我使用 @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 对象,因此我不必手动输入。

【问题讨论】:

    标签: java json gson


    【解决方案1】:

    您可以实现更通用的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。但是如果你初始化它们——比如空字符串""——那么它们就不是空的并且你不需要使用构建器方法.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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-07-19
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      相关资源
      最近更新 更多