-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Give Custom Deserializers access to the resolved target Class of the currently deserialized object #165
Comments
Can you suggest a way in which it would make sense to pass this information? Keep in mind that deserializers are stateless objects, so this information would need to be passed in context somehow; and should not incur significant additional overhead for cases where it is not needed. Another way of putting my question is whether this would be during construction of deserializer (and it being cached), or during operation. Jackson tries to put as much work as possible on former part, FWIW. |
i would suggest an interface similar to the ContextualDeserializer that a deserializer/serializer can implement and return a properly configured instance. |
So something like "TypeSpecificDeserializer" add-on interface? So compared to ContextualDeserializer, type for which deserializer is being built would be explicitly passed (and in case of root values, it wouldn't even be available). I also assume this should be resolved before ContextualDeserializer, so type-specific specialization would take place first, and then one could also implement ContextualDeserializer if that makes sense. I think that could work... |
Oh, one more question -- wouldn't it be possible to configure this on your end when adding custom deserializers? Although |
could you elaborate how they do that? afaik a deserialize call does not contain type information. |
I meant |
Ah. That works fine for (de)serializers that handle a specific type. but what about (de)serializers that handle a specific property, maybe of an (for them) unknown type? the type has to be known to jackson at (de)serialization but there is no way for such a (de)serializer to know it. over the last weeks i had several such cases. it is possible to work around that with the contextual(de)serializer interface. but that workaround misses information and therefor can fail in special scenarios. |
That's not how Jackson deserializers work -- they are bound to specific types. You can of course register single (de)serializer for all kinds of types, but if so, you will have to deal pass through the type and contextual information as it becomes available, creating distinct deserializer instances with that information (as necessary). So you sort of need to build more distinct instances incrementally, such that deserializer will know what kind of type it will be dealing with as part of construction process. This information will not be passed during actual deserialization calls, except (to limited degree) for polymorphic deserialization in which case |
i would do that, but the resolved property type is not available in a contextual way. |
I may have misunderstood your use case. So let me go back to basic question: how is your deserializer registered? So far I assume you are registering them via |
thats exactly right. the deserializer is used for a property of the type currently i just use the |
Just one more clarification: is this used with something like:
or by registering If latter, it still does not explain why you think type is not available. List (array, Map) deserializers do not handle value instances themselves, but delegate to value deserializers, and these are constructed and initialized like any other deserializers, including passing of type information. Apologies for tons of questions -- I just want to make sure I fully understand problem being solved. At this point Jackson API is big (and thick) enough that I am trying to limit number of additions. I do agree in that type information would be good to pass, and if |
its the annotation. |
Ok thanks. The request then makes sense. Another way to handle this would be to bite the bullet and consider addition of (de)serializer factory/builder annotation. This would allow passing as much context as necessary, and would be easy to extend. |
What's the status on this? I too would find this helpful. I'm trying to define a custom annotation and deserializer combo to suit my needs and I'll need information about the target class of the deserialization in order to apply the settings from the annotation and return the correct class. I could almost get there by maintaining the generic chain, but I can't because there's no way to do this in java.
So I would instead need to create subclasses for each different model, which is far from ideal. |
There is nothing planned or worked on for 2.5.0 to pass more information. One thing that is added for 2.5.0 (due to be released soon) is actual value being deserializer (after instance has been initialized), via |
Come to think of this, I don't think changing of |
This turned out relatively easy to implement, so now there is: class DeserializationContext {
public JavaType getContextualType() { ... }
} which will give expected type during call to |
…ich can be called by contextual deserializers to know nominal type for them, without needing to decipher it from `BeanProperty`
That's awesome. Thank you. |
…; planned to help with FasterXML#165
I don't understand how this will work? Do we have way to create deserializers without type information and then use |
@taypo Not quite. You will need to implement |
Jackson resolves the target class for a json object using parameter/property types, annotations, json properties or a parameter in the object mapper.
please give custom deserializers easy access to this information. currently it is nearly impossible to create a deserializer that works for multiple types. the only way would be to implement "contextualdeserializer" and access the bean property which is very complicated.
The text was updated successfully, but these errors were encountered: