7

In my project I have some JsonDeserializers to deserialize abstract types in collections. Now I have a type which has a Collection property. How can I instruct Jackson to deserialize the nested collection for me instead of doing it myself?

interface Person {
    String getName();
    void setName(String name);
}

class LonelyPerson implements Person { ... }
class SocialPerson implements Person {
    private List<Person> friends;
    ...
}

public class SocialPersonDeserializer extends JsonDeserializer<Person> {
    public Person deserialize(final JsonParser jp, final DeserializationContext ctx) throws IOException {
        ObjectCodec codec = jp.getCodec();
        JsonNode jsonNode = codec.readTree(jp);

        String name = jsonNode.get("name").asText();
        SocialPerson sp = new SocialPerson();
        p.setName(name);

        JsonNode friends = jsonNode.get("name").asText();
        for (JsonNode friendNode : friends) {
            sp.getFriends().add(/* How to desialize another person?? */);
        }
    }
}
Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
Bart
  • 17,070
  • 5
  • 61
  • 80
  • Yes, it is possible to read a nested object collection from the JsonParser inside the custom deserializer. Perhaps you do not even need a custom deserializer. Can you post a sample JSON? How do you distinguish between person types? – Alexey Gavrilov Aug 19 '14 at 15:14
  • @AlexeyGavrilov In my code I use a `type` property to identify different types of `Person`. So if a person matches a certain type it will be deserialized by the proper deserializer. – Bart Aug 19 '14 at 16:26
  • Have you tried to use the Jackson polymorphic deserialization? http://wiki.fasterxml.com/JacksonPolymorphicDeserialization . It may eliminate the need to custom deserializers. – Alexey Gavrilov Aug 19 '14 at 17:11
  • No I haven't. I will take a look at it when I get the time. Thank you for the link. – Bart Aug 19 '14 at 17:36

1 Answers1

0

In this case (ok it is old but for someone it could be an help) you actually have a nested recursive object, so you can simply extract the code to deserialize a person on a Node and iterate over his friendNodes invoking the same function

Something like

public class SocialPersonDeserializer extends JsonDeserializer<Person> {
    public Person deserialize(final JsonParser jp, final DeserializationContext ctx) throws IOException {
        ObjectCodec codec = jp.getCodec();
        JsonNode jsonNode = codec.readTree(jp);

       SocialPerson sp = deserializePerson(jsonNode);
       JsonNode friends = jsonNode.get("name").asText();
       for (JsonNode friendNode : friends) {
            sp.getFriends().add(deserializePerson(friendNode));
       }
       return sp;
   }

    protected SocialPerson deserializePerson(JsonNode jsonNode){
        String name = jsonNode.get("name").asText();
        SocialPerson sp = new SocialPerson();
        sp.setName(name);
       //other code, you could want to pass the codec or the parser to the method too
        return sp;
    }
}
Skyler Tao
  • 33
  • 1
  • 8
R.Litto
  • 385
  • 3
  • 14