(免责声明:极端过于简单化。实际情况要复杂得多。)
假设我有两个系统,Producer和Consumer。除了单个共享接口外,它们的代码完全独立:
public interface Thing {
String getName();
String getDescription();
int getPrice();
}
这个想法是Producer创建了一堆数据并通过HTTP将其作为JSON发送。 Producer有很多Thing的实现,每个都有额外的元数据和数据生成过程中所需的东西。
因为除了最顶层的薄层之外,生产者不需要任何杰克逊/序列化知识,所以序列化属性应该保留在Thing实现之外。由于将来很可能会增加实施的数量,因此对所有这些实施的混合使用很快就变得不可持续。据信将注释应用于Thing接口本身就足够了。
第一个简单的方法是在接口上使用@JsonSerialize注释。起初,这似乎有效,但导致了一个问题。 Thing的一些实现是枚举,导致Jackson只是将它们序列化为名称而不是界面中定义的字段。
一些谷歌搜索显示以下注释:
@JsonFormat(shape= JsonFormat.Shape.OBJECT)
虽然确实通过序列化字段而不是名称来解决问题,但它也 ,因为它也开始序列化未在Thing界面中定义的特定于实现的公共字段,从而产生由于包含未知条目的数据,不仅信息泄漏,而且消费者的反序列化失败。
由于进一步的谷歌搜索没有产生任何结果,我能想到的唯一解决方案是将所有这些字段标记为可忽略的,由于前面提到的原因,这是非常不受欢迎的。
有没有办法,简单地通过改变界面本身及其注释,来强制确切地说那些字段,不再是,不能少,应该在类和枚举时被序列化?
答案 0 :(得分:1)
当我和杰克逊合作时,我遇到了这个问题。反序列化失败是因为在反序列化期间,Jackson无法找到多态引用类型。
您应该使用@JsonTypeInfo注释您的界面。
类似的东西:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class")
您的问题中没有太多代码,因此这个答案。
答案 1 :(得分:0)
通常你应该能够强制使用某种类型:
@JsonSerialize(as=Thing.class)
与@JsonDeserialize
类似。
这不适用于枚举吗?