3

(免责声明:过于简单化。实际情况要复杂得多。)

假设我有两个系统,生产者和消费者。除了单个共享接口之外,它们的代码是完全独立的:

public interface Thing {
    String getName();
    String getDescription();
    int getPrice();
}

这个想法是生产者创建一堆数据并通过 HTTP 将其作为 JSON 发送。Producer 有一堆 Thing 的实现,每一个都有额外的元数据和数据生成过程所需的东西。

由于 Producer 不希望拥有任何关于 Jackson/序列化的知识,除了最顶层的薄层之外,序列化属性应该被排除在 Thing 实现之外。由于未来的实现量很可能会增长,因此为所有这些混合器很快就会变得不可持续。人们认为将注释应用于 Thing 接口本身就足够了。

第一个简单的方法是在接口上添加 @JsonSerialize 注释。起初,这似乎可行,但导致了一个问题。Thing 的一些实现是枚举,导致 Jackson 只是将它们序列化为它们的名称,而不是接口中定义的字段。

一些谷歌搜索显示了以下注释:

@JsonFormat(shape= JsonFormat.Shape.OBJECT)

虽然它确实通过序列化字段而不是名称来解决问题,但它做得太好了,因为它还开始序列化未在 Thing 接口中定义的特定于实现的公共字段,不仅导致信息泄漏,而且反序列化失败由于包含未知条目的数据,在消费者中。

由于进一步的谷歌搜索没有产生任何结果,我能想到的唯一解决方案是将所有这些字段标记为可忽略,由于前面提到的原因,这是非常不受欢迎的。

有没有什么办法,仅仅通过改变接口本身和它的注释,来强制那些字段,不多也不少,在涉及到类和枚举时都应该被序列化?

4

2 回答 2

1

当我与杰克逊一起工作时,我遇到了这个问题。反序列化失败是因为在反序列化期间,Jackson 无法找到多态引用类型。

您应该使用@JsonTypeInfo 注释您的界面。

就像是:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class")

您的问题中没有太多代码,因此有这个答案。

于 2013-05-08T14:59:08.777 回答
0

通常,您应该能够通过以下方式强制使用某些类型:

 @JsonSerialize(as=Thing.class)

同样与@JsonDeserialize. 这不适用于枚举吗?

于 2017-06-02T21:05:30.140 回答