-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support parameterized type deserialization by passing JavaType to deserializer #57
Comments
I am not sure I really understand what is being requested here so I will start with noting that what Since the type is used for locating initial deserializer (possibly modified by resolution via Sometimes developers wish type was available, to allow for general-purpose multi-type deserializers: this is not provided and I do not see benefit of adding machinery to store an pass type information (esp. via new argument; but if passed contextually, requires book-keeping as well). If deserializers want to know it, they need to retain it when first requested. I'll leave this issue open but I do not see much benefit in trying to do this, adding complexity and overhead. |
(transferred to "jackson-future-ideas" since this would be a major rewriting of much of databind internals, touching every existing deserializer implementation as well as most abstractions) |
The context of this is parameterized types. For example the type I ran into it with is: Result<V, E>. To complicate matters Result is a sealed Kotlin class, which for our purposes is equivalent to an abstract class, so that the only object instances of Result type are subtypes (either an Ok or an Error). I don't own the class so I can't add annotations to it, so I need to write my own serializer/deserializer for it. Ideally I would like to write one deserializer that would work for all Result objects, but I can't because Result isn't really a single type -- it's a family of types -- and I can't deserialize it unless I know exactly which member of that family I'm deserializing to. I don't need a separate deserializer for every possible member of this family, a single deserializer will do, but only if I have access to that type information. In the example I pointed you to I wrote a single deserializer, but I had to register a separate instance of it for every combination of types I used with Result. It would have been better if I could have instantiated a single deserializer that would receive the type information it needs at run time. I don't think the change I'm asking for needs to be as large as you've said. If the type data were put into the context then no existing deserializers would need to change -- only future deserializers would (optionally) use that data. If I'm not mistaken each deserialization gets its own context so there wouldn't be concurrency issues. In the code I've traced through the JavaType object was present through almost the entire call chain so it seems like there's ample opportunity to add it to the context just before the deserializer is called. I agree that adding it to the deserialize() call would be very disruptive. You'd almost want to add an entirely new deserializer type to the API to accommodate that, and it would still be a big change. |
I am confused by "I had to register a separate instance of it for every combination of types I used with Result" -- this is not necessary when implementing
As to
but only during construction of deserializer: this may or may not be useful in your situation. |
Here's the code I'm working with.
|
Looks like But as I said a few times, Please instead implement |
That's what I did: I instrumented the |
No, I don't think that makes sense: you should construct deserializer with |
Let me see if I understand what you're saying: if I have a parameterized type like Result<V,E> and I want to be able to use it with a bunch of separate types then it make sense for me to register a separate deserializer instance for each one. So maybe I'd have some different kinds of results like Person, Location, Product, Price. And I might have some different kinds of errors that I might want to report like, NotFound, Forbidden, Timeout, InternalError. So then I'd register deserializers for every combination: Result<Person, NotFound>, Result<Person, Forbidden>, Result<Person, Timeout>, Result<Person, InternalError>, Result<Location, NotFound>, etc... for all 16 possibilities? It's definitely possible to do, I just thought it would be valuable to be able to register a single deserializer that could handle every possible combination no matter how many there are. |
The way callbacks work is that you create specific deserializers on demand -- and yes, you will end up with all permutations, potentially. That is the fundamental design of the system; it is expected that (de)serializer knows type it is being used for when constructed and initialized. |
Is your feature request related to a problem? Please describe.
I want to be able to (de)serialize objects of type
com.github.michaelbull.result.Result
which is a type I don't own and which has no Jackson annotations. I want to do custom serialization so I can communicate with services I control written in Ruby that have Json support for equivalentResult
types, which means that I'd like to keep Java class data off the wire. I know the type parameters for theResult
object I want to deserialize at the point in time when I callObjectMapper.readValue()
and pass a JavaType with that information into that call.Because I want to deserialize multiple flavors of
Result
I instantiate multiple instances of its deserializer passing the type information for each flavor into the constructor. I cannot register these different instances with the sameObjectMapper
, however becauseSimpleDeserializers
registers deserializers based on JavaClass
objects instead ofJavaType
s.This is a Spring application (written in Kotlin) and I would like to be able to have a singleton
ObjectMapper
that is configured for use throughout the entire application. As it stands I have no way to configure one that can deserialize multiple flavors of the same parameterized type.Describe the solution you'd like
I want to receive the
JavaType
of the object to be deserialized in thedeserialize()
call, either as a new parameter or as part of theDeserializationContext
parameter. That way I can use the same instance of the deserializer to deserialize multiple flavors of the same parameterized type by examining the reified values of those parameters at runtime.Usage example
I have a toy project that illustrates what I'm trying to do except outside of the context of Spring here: https://github.com/pgoodwin/serialization-experiment
Additional context
The text was updated successfully, but these errors were encountered: