I am using Jackson for JSON serialization and have written a couple custom String
serializers, one for each getter method of a class. The methods each return the same type, Set<String>
, but each uses a different serializer.
Unfortunately, Jackson is not using each serializer, one for each method, but is using one serializer for both. It appears to take whatever method comes first alphabetically and uses its serializer for both methods. What I expect is that the serializer annotated on the first method is used for the first method, and the serializer annotated on the second method is used on the second method. Debugging appears to indicate that Jackson has the serializers in a map keyed by return type of the method (which is the same for both).
An Example:
public class FooBar {
private Set<String> foos = new HashSet<String>();
private Set<String> bars = new HashSet<String>();
@JsonProperty("FooWrapper")
@JsonSerialize(contentUsing = FooSerializer.class)
public Set<String> getFoos() {
return foos;
}
@JsonProperty("BarWrapper")
@JsonSerialize(contentUsing = BarSerializer.class)
public Set<String> getBars() {
return bars;
}
}
Any suggestions on how to get the getFoos()
method to serialize with a FooSerializer
, and the getBars()
method to serialize with the BarSerializer
? In this example, the BarSerializer
is invoked for both methods.
Note, if I change the signature of one of the methods to another collection type so they are different - List<String>
for example - the serialization works.
Thanks in advance.
I think what you are trying to achieve isn't possible in version 1.9.xx when using an
ObjectMapper
in combination with@JsonSerialize(contentUsing = BarSerializer.class)
.Jackson does indeed cache the serializers, and it caches them based on the
JavaType
(in this caseSet<String>
) that's associated with the serializer. SeeStdSerializerProvider.findValueSerializer(JavaType valueType, BeanProperty property)
.Although the
BeanProperty
is passed to this method, it isn't used as part of the cache key. You could subclassStdSerializerProvider
and take theBeanProperty
parameter into account when caching value serializers, but that's probably not the easiest way to solve your problem.As a quick fix would be to use
@JsonSerialize(using = FooCollectionSerializer.class)
and deal with serializing the collection yourself. By doing this, the serializer is directly coupled to theBeanPropertyWriter
used to serialize the property. When using@JsonSerialize(contentUsing = BarSerializer.class)
there's no serializer coupled to theBeanPropertyWriter
which triggers the serializer lookup that caches the serializers based on theJavaType