If you are reading this, then it is highly possible that you know that currently Jackson @Unwrapped does not play nice with type information.
Actually, in my case the issue was only with serialization. Jackson did recognize my type information, embedded as @type property while deserializing. On serialization it produced something like {:{"a":1}}. But I wanted {"@type":"myType", "a":1}.
Jackson has this issue registered in issue tracker, but it looks like correct fix is too complex. But I still want inheritance with unwrapping :) Here is a snippet that fixes issue.
NB! This code snippet fixes issue, but it's global effect is not confirmed :D
Actually, in my case the issue was only with serialization. Jackson did recognize my type information, embedded as @type property while deserializing. On serialization it produced something like {:{"a":1}}. But I wanted {"@type":"myType", "a":1}.
Jackson has this issue registered in issue tracker, but it looks like correct fix is too complex. But I still want inheritance with unwrapping :) Here is a snippet that fixes issue.
NB! This code snippet fixes issue, but it's global effect is not confirmed :D
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class UwrappedWithTypeInformation { | |
public static void main(String... args) { | |
new ObjectMapper().registerModule(new SimpleModule() { | |
public void setupModule(SetupContext context) { | |
super.setupModule(context); | |
context.addBeanSerializerModifier(new BeanSerializerModifier() { | |
public JsonSerializer<?> modifySerializer( | |
SerializationConfig config, | |
BeanDescription beanDesc, | |
JsonSerializer<?> serializer) { | |
if (serializer instanceof BeanSerializer) { | |
return new BeanSerializer((BeanSerializerBase) serializer) { | |
@Override | |
public JsonSerializer<Object> unwrappingSerializer(NameTransformer unwrapper) { | |
return new UnwrappingBeanSerializerWithTypeInformation(this, unwrapper); | |
} | |
}; | |
} | |
return serializer; | |
} | |
}); | |
} | |
}); | |
} | |
public static class UnwrappingBeanSerializerWithTypeInformation extends UnwrappingBeanSerializer { | |
public UnwrappingBeanSerializerWithTypeInformation(BeanSerializerBase src, NameTransformer transformer) { | |
super(src, transformer); | |
} | |
@Override | |
public void serializeWithType(Object bean, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException { | |
if (_objectIdWriter != null) { | |
_serializeWithObjectId(bean, jgen, provider, typeSer); | |
return; | |
} | |
jgen.writeStringField(typeSer.getPropertyName(), typeSer.getTypeIdResolver().idFromValue(bean)); | |
if (_propertyFilterId != null) { | |
serializeFieldsFiltered(bean, jgen, provider); | |
} else { | |
serializeFields(bean, jgen, provider); | |
} | |
} | |
} | |
} |
This solution fails, if the nested class uses one of the following features: @JsonIgnoreProperties, @JsonFilter or @JsonIdentityInfo.
ReplyDeleteSee discussion at
https://groups.google.com/forum/#!topic/jackson-user/Aw0y6XgToH8
and the open issue:
https://github.com/FasterXML/jackson-databind/issues/1427
Cheers, Paolo