Reputation: 8171
(Disclaimer: Extreme oversimplification. The actual scenario is considerably more complex.)
Say I have two systems, Producer and Consumer. Their code is completely independent, aside from a single shared interface:
public interface Thing {
String getName();
String getDescription();
int getPrice();
}
The idea is that Producer creates a bunch of data and sends it as JSON over HTTP. Producer has a bunch of implementations of Thing, each with additional pieces of metadata and stuff required in the data generation process.
As it's undesirable for Producer to have any kind of knowledge of Jackson/serialization aside from a thin layer at the very top, serialization attributes should be kept out of the Thing implementations. Due to the amount of implementation being very likely to grow in the future, having mixins for all of them quickly becomes unsustainable. It was believed to be sufficient to apply annotations to the Thing interface itself.
The first simple approach was a @JsonSerialize annotation on the interface. At first, that seemed to work, but resulted in a problem. Some of the implementations of Thing are enums, resulting in Jackson simply serializing them as their name instead of the fields defined in the interface.
Some googling revealed the following annotation:
@JsonFormat(shape= JsonFormat.Shape.OBJECT)
While it did indeed solve the problem by serializing the fields instead of the name, it did it too well as it also began serializing the implementation-specific public fields not defined in the Thing interface, resulting not only in information leak, but also failed deserialization in Consumer due to the data containing unknown entries.
As further googling didn't yield any results, the only solution I can think of is marking all those fields as ignorable, something that is extremely undesirable due to the previously mentioned reasons.
Is there any way, simply by altering the interface itself and its annotations, to enforce that exactly those fields, no more, no less, should be serialized both when it comes to classes and enums?
Upvotes: 3
Views: 1515
Reputation: 116610
Usually you should be able to force use of certain type with:
@JsonSerialize(as=Thing.class)
and similarly with @JsonDeserialize
.
Does this not work with enums?
Upvotes: 0
Reputation: 5654
I have this issue when I was working with Jackson. The deserialization fails because, during deserialization, Jackson is unable to find the polymorphic reference type.
You should be annotating your interface with @JsonTypeInfo.
Something like:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class")
There isn't much of code in your question and hence this answer.
Upvotes: 1