How to make work TypeResolverBuilder with registerSubtypes
See original GitHub issueHello,
I can’t use annotations because it’s a external library so I neeed to register subTypes for an interface and set custom type handler.
I searched and tried multiple guides but without sucess
This is the code that I tried but without sucess, typeResolver is working but Jackson not matching the registered subTypes with the type.
TypeResolverBuilder<?> typeResolver = new ObjectMapper.DefaultTypeResolverBuilder(ObjectMapper.DefaultTyping.NON_FINAL, BasicPolymorphicTypeValidator.builder()
.allowIfBaseType(BeOutMessage.class)
.build());
typeResolver.init(JsonTypeInfo.Id.NAME, null);
typeResolver.inclusion(JsonTypeInfo.As.PROPERTY);
typeResolver.typeProperty("action");
mapper.registerSubtypes(
new NamedType(InitRequestBeMessage.class, ActionType.INIT_REQUEST.name()),
new NamedType(PlayRequestBeMessage.class, ActionType.PLAY_REQUEST.name())
);
mapper.setDefaultTyping(typeResolver);
I get this error:
typecom.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'INIT_REQUEST' as a subtype of `classpath.BeOutMessage`: known type ids = []
The most easiest solution that I found is use JsonDeserializer:
public class BeOutMessageDeserializer extends JsonDeserializer<BeOutMessage> {
@Override
public BeOutMessage deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonNode jsonNode = p.getCodec().readTree(p);
Class<? extends BeOutMessage> entityClass = BeOutMessageType.valueOf(jsonNode.get("action").asText()).entityClass();
return ((ObjectMapper)p.getCodec()).readValue(jsonNode.toString(), entityClass);
}
}
But I don’t like it and I don’t think that is efficient enough like the JsonSubTypes. How would be the proper way to do it at runtime?
Thank you!
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
Json deserialization into other class hierarchy using Jackson
You do then need to register subtypes (either by calling ObjectMapper.registerSubtypes() , or by using @JsonSubTypes annotation). – StaxMan. Apr ...
Read more >Polymorphic resolution without annotations, looking for ...
Therefore my plan is to use a CustomTypeResolverBuilder to which I'm registering all subtypes in a generic way. What I have found so...
Read more >ObjectMapper (jackson-databind 2.14.1 API) - javadoc.io
Overridable factory method, separate to allow format-specific mappers (and specifically XML-backed one, currently) to offer custom TypeResolverBuilder subtypes.
Read more >TypeResolverBuilder (jackson-databind 2.9.0 API) - FasterXML
To create builders when "default typing" is used; if so, type information is automatically included for certain kind of types, regardless of annotations....
Read more >Jackson - ObjectMapper Class - Tutorialspoint
It is also highly customizable to work both with different styles of JSON ... Customized TypeResolverBuilder that provides type resolver builders used with ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
After some performance tests agaisnt mixin I got this results:
And it improves a little bit when using with mapper.readerFor. Ergo we will use mixin and I hope that other devs can get usefull this issue for info.
Thanks @yawkat, I think we can close the issue if there is nothing else to add
One note after the fact: if you use “Default Typing”, registration of subtypes has no effect – Default Typing specifically forces use of class names (and potentially opens up security holes). Subtype registration is (only) used when Type Ids are used instead – a safer approach, but one that does require mapping.
It sounds like mix-ins could work here, but use of
TypeResolverBuilder
would not make any sense to me.