Closed Feniksovich closed 7 months ago
It seems I just should use DeserializationContext to access other registered (de-)serializatiors, isn't it?
At first I assumed resolution of ObjectCodec
is not made at deserialize(JsonParser jp, DeserializationContext ctxt)
stage, but others' deserialization works.
Could you please share how House
, Person
and Flat
classes are declared?
Also, could you try deserializing like below? Below is from jackson-databind
test suite.
I can't make time yet, to confirm but seems pretty reasonable way to go .
@Override
public Leaf deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonNode tree = (JsonNode) jp.readValueAsTree();
Leaf leaf = new Leaf();
leaf.value = tree.get("value").intValue();
return leaf;
}
At first I assumed resolution of ObjectCodec is not made at deserialize(JsonParser jp, DeserializationContext ctxt) stage, but others' deserialization works.
Correct and it's strange thing. I'm new to Jackson, I've used some examples from the internet to implement custom deserializers. Examples include line like parser.getCodec().readTree(parser)
to obtain JSON tree without setting the ObjectCodec explicitly.
Could you please share how House, Person and Flat classes are declared?
Please see this gist: https://gist.github.com/Feniksovich/4711bf5570661c915cd9936f56e0b932
Also, could you try deserializing like below? [ ... ]
I replaced JsonNode tree = parser.getCodec().readTree(parser)
with JsonNode tree = parser.readValueAsTree()
in every deserializator and got following exception:
However, I just tried to use DeserializationContext
to read tree and it's works. Is it correct and expected solution?
@Override
public Person deserialize(JsonParser parser, DeserializationContext context) throws IOException {
final JsonNode tree = context.readTree(parser);
// ...
}
However, I just tried to use DeserializationContext to read tree and it's works. Is it correct and expected solution?
Sure, I checked the jackson-databind
test suite and there seems to be a couple of usecases doing the same. if it works, why not. Sorry again for late reply! 🙏🏼 @Feniksovich
However, I just tried to use DeserializationContext to read tree and it's works. Is it correct and expected solution?
Sure, I checked the
jackson-databind
test suite and there seems to be a couple of usecases doing the same. if it works, why not. Sorry again for late reply! 🙏🏼 @Feniksovich
Thank you for your assistance, @JooHyukKim!
Just wondering how it should be implemented by design, but anyway thank you for assistance! @JooHyukKim
I am hoping that we will have more guidance on how to implement custom modules and de/serializers, eventually. Thank you for the feedback!
Quick note: ideally, you would never need to call JsonParser.getCodec()
from a deserializer, custom or otherwise. If you do, it's a flaw somewhere.
Instead, everything needed should be accessible via either JsonParser
or -- in most cases -- DeserializationContext
(like suggested). So, f.ex instead of
@Override
public Leaf deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonNode tree = (JsonNode) jp.readValueAsTree();
it should be possible to use
JsonNode tree = ctxt.readTree(jp);
Linkage of JsonParser.getCodec()
is bit problematic, although it should also work. The trouble (aside from it not being assigned for some reason) is that when JsonParser
calls methods in ObjectMapper
, the effective DeserializationContext
is not available and new one gets created. This in turn can have negative consequences on access to things.
So, yes, if at all possible, first look into DeserializationContext
for functionality.
So, yes, if at all possible, first look into DeserializationContext for functionality.
@cowtowncoder, thank you for detailed explanation! I really appreciate prompt feedback from your team.
Thank you @Feniksovich !
Search before asking
Describe the bug
Similar resolved issue: https://github.com/FasterXML/jackson-databind/issues/2038 I keep receive NPE on
JsonParser#getCodec()
in a custom JsonDeserializer when trying to deserialize myHouse
POJO:There are also two registered JsonSerializer/JsonDeserializer for the
Person
andFlat
POJOs and they work fine. But onHouse
POJO deserialization I receive NPE onJsonParser#getCodec()
invoke in the PersonDeserializer (see below).Stacktrace
```java java.lang.NullPointerException: Cannot invoke "com.fasterxml.jackson.core.ObjectCodec.readTree(com.fasterxml.jackson.core.JsonParser)" because the return value of "com.fasterxml.jackson.core.JsonParser.getCodec()" is null at com.feniksovich.lab7.serializers.jackson.PersonSerializationModule$PersonDeserializer.deserialize(PersonSerializationModule.java:32) at com.feniksovich.lab7.serializers.jackson.PersonSerializationModule$PersonDeserializer.deserialize(PersonSerializationModule.java:29) at com.fasterxml.jackson.databind.DeserializationContext.readValue(DeserializationContext.java:992) at com.fasterxml.jackson.databind.DeserializationContext.readValue(DeserializationContext.java:979) at com.feniksovich.lab7.serializers.jackson.HouseSerializationModule$HouseDeserializer.deserialize(HouseSerializationModule.java:44) at com.feniksovich.lab7.serializers.jackson.HouseSerializationModule$HouseDeserializer.deserialize(HouseSerializationModule.java:38) at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3848) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3816) ```Version Information
2.17.0
Reproduction
House
object and try to deserialize it.JsonParser#getCodec()
.PersonSerializationModule
```java public class PersonSerializationModule extends SimpleModule { public PersonSerializationModule() { addSerializer(Person.class, new PersonSerializer()); addDeserializer(Person.class, new PersonDeserializer()); } private static class PersonSerializer extends JsonSerializerFlatSerializationModule
```java public class FlatSerializationModule extends SimpleModule { public FlatSerializationModule() { addSerializer(Flat.class, new FlatSerializer()); addDeserializer(Flat.class, new FlatDeserializer()); } private static class FlatSerializer extends JsonSerializerHouseSerializationModule
```java public class HouseSerializationModule extends SimpleModule { public HouseSerializationModule() { addSerializer(House.class, new HouseSerializer()); addDeserializer(House.class, new HouseDeserializer()); } private static class HouseSerializer extends JsonSerializerExpected behavior
Successful deserialization of the
House
object.Additional context
No response