-
-
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
Allow deserialization of unknown Enums using a predefined value #1126
Allow deserialization of unknown Enums using a predefined value #1126
Conversation
See Jackson Databind PR FasterXML/jackson-databind#1126 for more details
Ok makes sense at usage level. I'll have to think about annotation used; it would be nice if an existing one could be reused, but at the same time it is dangerous to overload meaning too much, so this may work fine. One suggestion for implementation is that the only way to access any of the annotations should be via On questions:
|
Ok, i can do that, but i might need some more guidance because currently, only the method
Yeah, a new method seems a better idea since i wasn't able to think of a way of modifying an existing one to suit both use-cases. I could make a change in the
And the
Let me know your thoughts on how to handle the lack of an AnnotationIntrospector as mentioned above and i'll commit the changes for you to review. |
valueOf.setAccessible(true); | ||
return enumCls.cast(valueOf.invoke(null, field.getName())); | ||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { | ||
java.util.logging.Logger.getLogger(EnumResolver.class.getName()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cowtowncoder based on your comment on logging, i'm not sure if it would it be best to wrap this into an exception and let it bubble up or just swallow it and return null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I think I would start by throwing an exception (wrapping in IllegalArgumentException
, perhaps -- that gets converted into more meaningful JsonProcessingException
or such, with more information). It will be easier to allow suppressing it later on if need be.
@AlejandroRivera Yes, inaccessibility of information can often be problematic: originally Adding new version of method is acceptable if there is a way to retrofit old code, make it call new method, deprecate old method (you may be able to find examples). This not trivial to make work as intended wrt backwards-compatibility (it tends to violate things as this part of Public API and not fully internal), but there is a trade-off to make wrt improving behavior vs maximal compatibility. So basically I am open to suggestions; I would like to help more, but at this point I am limited by time (last work day before vacation). I will be back with more time in about 1 week and should be able to help more if need be. I will try to check emails and updates, but response times may be bit slow. |
a0f36f3
to
84424ca
Compare
…efault values. The abstract `AnnotationIntrospector` method always returns `null` because Java has no notion of default Enum values. `JacksonAnnotationIntrospector` relies on ClassUtil to find the `@JsonEnumDefaultValue` annotated Enum value.
After examining the codebase a bit better, i think i found the ideal way of handling the logic without creating new package dependencies. It goes as follows:
The only downside I see of this approach is the link from I'm planning on looking some more through the code to see if it's possible to pass the reference from other places, but in order to maintain backwards binary compatibility (since you mentioned that this EnumResolver is somewhat of a public-API), i'm going to need to have two methods (one with the AnnotationIntrospector and one without) and will have to hardcode a default instance to use (or even a null value). How does that sound? PS. Enjoy your vacation! |
…ards compatibility. Also removed leftover imports that weren't needed anymore.
@cowtowncoder: I think I'm done with my changes. Let me know what you think once you have time to review. |
@AlejandroRivera Thank you for the updates! I am leaving for a 1 week vacation now, so it will take a while, but I will review this after I come back. Given that it involves changes to API it can (and needs to) go in 2.8, so we have quite a bit of time. |
…nown-enums-using-default Allow deserialization of unknown Enums using a predefined value
@AlejandroRivera Looks good, good job! I merged it, made minor tweaks (need to delegate via introspector pair), will be included in 2.8. |
Sweet! Thanks for the tweaks 👍 LMK if i can help with anything else related to this change (e.g. documentation or anything). |
@AlejandroRivera I think we are good -- your patch was very well made, including javadocs and all. Much appreciated! |
I was actually thinking of the documentation found in the Wiki, but i take it you've got that covered. Let me know otherwise :) |
@AlejandroRivera Ah. Actually yes good point: it would be great to get an update for https://github.com/FasterXML/jackson-databind/wiki Not sure what'd be the best way; perhaps if you can add a snippet here for change? |
Added documentation for the config here: Also here https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations#deserialization-details |
Excellent. |
Use case:
When using Jackson to deserialize a json payload coming from a 3rd party provider, it's common not to have the entire list of enum values required to support proper Enum deserialization. Jackson already offers a way to deserialize unknown values as
null
, nevertheless, it can be more useful to be able to deserialize them into a pre-determined value (perhaps named "UNKNOWN") to avoid NPEs or other issues.The current way to achieve this desired effect is to have a custom deserializer or a
@JsonCreator
constructor. This approach, while effective, is also somewhat cumbersome since we lose the ability to rely on other annotations like@JsonProperty
or@JsonValue
to serialize and deserialize values.Proposal
Through the creation of a new Jackson annotation
@JsonEnumDefaultValue
, developers should be able to annotate a specific enum that they wish to use as default. This annotation, along with a new DeserializationFeature toggle, should make it easy to accomplish the desired effect.Complimentary Jackson annotation:
Open questions: