【问题标题】:Use a custom deserializer only on fields?仅在字段上使用自定义反序列化器?
【发布时间】:2013-03-10 18:01:27
【问题描述】:

我使用一种复制机制来同步两个数据库。为了在数据库之间进行通信,我使用 Gson 将对象序列化为 JSON。每个对象都有一个 UUID 来识别它。为了避免发送最新的项目,当对象包含在要复制的对象的字段中时,我使用对象 UUID。

我们有以下课程:

public class Entity {
    String uuid;

// Getters and setters..
}

public class Article extends Entity {
    String name;
    Brand brand;

// Getters and setters..
}

public class Brand extens Entity {
    String name;
    Producer producer 

// Getters and setters..
}

public class Producer extends Entity {
    String name;

// Getters and setters..
}

如果我序列化文章,它的 JSON 表示将如下所示:

{"brand":"BrandÖ179d7798-aa63-4dd2-8ff6-885534f99e77","uuid":"5dbce9aa-4129-41b6-a8e5-d3c030279e82","name":"Sun-Maid"}

其中“BrandÖ179d7798-aa63-4dd2-8ff6-885534f99e77”是类(“品牌”)和 UUID。

如果我序列化我期望的品牌:

{"producer":"ProducerÖ173d7798-aa63-4dd2-8ff6-885534f84732","uuid":"5dbce9aa-4129-41b6-a8e5-d3c0302w34w2","name":"Carro"}

在杰克逊,我会将文章类更改为:

public class Article {
    String uuid;
String name;
    @JsonDeserialize (using = EntityUUIDDeserializer.class) @ JsonSerialize (using = EntityUUIDSerializer.class)        
    Brand brand;

// Getters and setters..
}

并实现自定义序列化器和反序列化器以返回 UUID 而不是对象。

Gson 没有 @JsonDeserialize 注释。

如果我们像这样安装序列化器和反序列化器:

Gson gson = new GsonBuilder()
          .registerTypeAdapter(Producer.class, new EntityUUIDDeserializer())
          .registerTypeAdapter(Brand.class, new EntityUUIDDeserializer())  
          .registerTypeAdapter/Producer.class, new EntityUUIDSerializer())
          .registerTypeAdapter(Brand.class, new EntityUUIDSerializer())                 
          .create();

我们可以序列化文章和品牌。

通过

反序列化文章
Article article= gson.fromJson(inputJSONString, Article.class);

工作正常,但是

Brand brand= gson.fromJson(inputJSONString, Brand.class);

不工作。我想问题是当我们反序列化一个品牌时,我们让品牌的反序列化器尝试返回一个 UUID 字符串,但我们希望反序列化器返回一个品牌对象。

有没有办法避免创建两个不同的 Gson 对象?两个不同的 Gson 对象的问题是当您想要反序列化一个同时包含 Article 和 Brand 的对象时。

【问题讨论】:

    标签: gson


    【解决方案1】:

    您编写序列化器/反序列化器并将其注册到 Gson(使用 GsonBuilder)。

    https://sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserialization

    Gson g = new GsonBuilder()
                  .registerTypeAdapter(Producer.class, new MyProducerDeserializer())
                  .registerTypeAdapter(Producer.class, new MyProducerSerializer())                  
                  .create();
    

    当您序列化/反序列化您的Brand 类时,它会将它们用于其中包含的Producer 字段。

    【讨论】:

    • 如果我们只序列化包含实体的实体,您的解决方案就可以正常工作。但是,如果我们有一个包含 Brand 对象的 Article 对象,我们将无法正常工作。我们有针对该用例的解决方案吗?抱歉,用我糟糕的代码示例误导了你。
    • 为什么它不起作用?您为特定类注册一个序列化器/反序列化器。当遇到那个类时,它们就会被使用。在您编辑的案例中,您可以将它们注册为Brand.class。它类似于您在 Jackson 中使用的注释,只是它处于更全局的级别。
    • 你的权利,我又一次糟糕地解释了这个问题。请看我对问题的改变。
    猜你喜欢
    • 1970-01-01
    • 2019-02-24
    • 2016-02-12
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 2023-03-03
    • 2017-05-21
    • 1970-01-01
    相关资源
    最近更新 更多