Is there any way to get a hold of ObjectMapper from within a JsonDeserializer

15 views
Skip to first unread message

Bojan Tomic

unread,
Dec 25, 2017, 3:16:57 PM12/25/17
to jackson-user
The subject line is pretty much the whole question: can ObjectMapper be accessed from JsonDeserializer#deserialize in any way at all?

If it is absolutely out of the question (and only in that case), is it possible to achieve an equivalent of: ObjectMapper#readValue(String, JavaType) using JsonParser and/or DeserializationContext? How about ObjectMapper#convertValue(Object, JavaType)?

Tatu Saloranta

unread,
Dec 26, 2017, 4:02:21 PM12/26/17
to jackson-user
On Mon, Dec 25, 2017 at 12:16 PM, Bojan Tomic <veg...@gmail.com> wrote:
> The subject line is pretty much the whole question: can ObjectMapper be
> accessed from JsonDeserializer#deserialize in any way at all?

There is, although it's bit obscure and for a good reason: you should
not do that, at all (*),
if possible. And generally it is possible.

If you do want to do it, nonetheless, the route is via `JsonParser`
and method `getCodec()`,
which can be case as `ObjectMapper`, safely. But as per above, it's
the last resort if everything else fails.

> If it is absolutely out of the question (and only in that case), is it
> possible to achieve an equivalent of: ObjectMapper#readValue(String,
> JavaType) using JsonParser and/or DeserializationContext? How about
> ObjectMapper#convertValue(Object, JavaType)?

The way deserializers are designed to work is to use delegation to
other deserializers.
Access to these is via `DeserializationContext`: either during
initialization (usually method `createContextual()`
when deserializer implements `ContextualDeserializer`), or at runtime,
during `deserialize()` call.
Former is significantly more efficient as access is only done once
during construction: but it may not matter
a lot in specific cases.

Either way, method to use varies depending on details, there are
multiple `findXxxDeserializer()` calls: but if
you have no special configurations or customizations to worry about,
`findContextualValueDeserializer` is probably
the best (from `createContextual()` directly, or if you have stored
ref to BeanProperty, during runtime).
Another possibility is just using `findRootValueDeserializer()`, which
only requires type and as such is easier to
call from `deserialize()` directly.

I hope this helps,

-+ Tatu +-

(*) Why not do that? `ObjectMapper` has no context of currently active
deserialization, like Attributes set, or
even some of configuration. It has to create such context, adding
overhead and possibly losing information you need.
This may or may not be problematic for custom types (or non-structured
standard types like `String`, numbers).
So you are basically missing the active `DeserializationContext` and
that can have side effects.

Bojan Tomic

unread,
Dec 27, 2017, 5:16:11 AM12/27/17
to jackson-user
Thanks again for such a detailed advice! I sincerely appreciate the effort. Very helpful!
Reply all
Reply to author
Forward
0 new messages