I’ve been using a custom typeId resolver for one of my classes, so far I’ve been leaning on the annotation support:
@JsonTypeInfo( use = JsonTypeInfo.Id.CUSTOM, include = JsonTypeInfo.As.PROPERTY, property = "@type") @JsonTypeIdResolver(ColumnDefinitionTypeResolver.class)
But now I need to customize the creation of the type resolver by passing some other dependencies to it via constructor or setters, and since Jackson is the one who instantiate it I can’t find a way around it.
Is there a way to configure the ObjectMapper to use a TypeIdResolver instead of relying on annotations?
Regards
Advertisement
Answer
So you have two options:
1) If you’re set on using the @JsonTypeIdResolver
your stuck using static
state in your TypeIdResolver
. This probably isn’t what you want.
The default JacksonAnnotationIntrospector
will try to create an instance of the type you provide using JsonTypeIdResolver
per its default constructor. There is currently no way to configure it to do otherwise.
public final class ColumnDefinitionTypeResolver implements TypeIdResolver { // You could rely on static state. public static String SOME_ACCESSIBLE_OBJECT = null; public ColumnDefinitionTypeResolver() { // This is what gets called. } } ColumnDefinitionTypeResolver.SOME_ACCESSIBLE_OBJECT = "I can affect the implementation from here, but using static state ... be careful";
2) Is create a module to handle deserialization of your type and subtypes.
SimpleModule columnDefinitionModule = new SimpleModule("colDefMod", new Version(1, 0, 0, null)) .addDeserializer(ColumnDefinition.class, new JsonDeserializer() { @Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Need to read the type out and then use ObjectMapper to deserialize using the correct token } }) .registerSubtypes(...); // add your subtypes here. (new ObjectMapper()).registerModule(columnDefinitionModule);
For more detailed examples, see Jackson documentation How-To: Custom Deserializers.