I am trying a combination of @JsonValue
and @JsonSerialize
. Let's start with my current container class:
public class Container {
private final Map<SomeKey, Object> data;
@JsonValue
@JsonSerialize(keyUsing = SomeKeySerializer.class)
public Map<SomeKey, Object> data() {
return data;
}
}
In this case, the custom serializer SomeKeySerializer
is not used.
If I change the container as following, the serializer is called:
public class Container {
@JsonSerialize(keyUsing = SomeKeySerializer.class)
private final Map<SomeKey, Object> data;
}
However, this is not what I want, as this introduces another 'data' level in the output JSON.
Is it possible to combine @JsonValue
and @JsonSerialize
in some way?
I could always write another custom serializer for Container
, which more or less does the same as the functionality behind @JsonValue
. This would be more or less a hack, in my opinion.
Jackson version: 2.6.2
Have you tried using
@JsonSerialize(using = SomeKeySerializer.class)
instead ofkeyUsing
?Doc for using() says:
...while for keyUsing you get:
Tested it out myself and it works...
This is the output when I'm NOT using
com.fasterxml.jackson.annotation.JsonValue
And this is the output when I'm using
com.fasterxml.jackson.annotation.JsonValue
This combination seems to do what you want: make a Converter to extract the Map from the Container, and add @JsonValue to SomeKey itself to serialize it:
I simply can't get annotating an accessor method of Container to DTRT at all easily, not in combination with @JsonValue. Given that @JsonValue on the container is basically designating a converter anyway (that is implemented by calling the annotated method), this is effectively what you're after, although not as pleasant as it seems it should be. (tried with Jackson 2.6.2)
(Something I learned from this: key serializers aren't like normal serializers, even though they implement JsonSerializer just the same. They need to call writeFieldName on the JsonGenerator, not writeString, for example. On the deserialization side, the distinction between JsonDeserializer and KeyDeserializer is spelled out, but not on the serialization side. You can make a key serializer from SomeKey with @JsonValue, but not by annotating SomeKey with @JsonSerialize(using=...), which surprised me).