如何让Jackson在自定义反序列化器中反序列化嵌套对象

7
在我的项目中,我有一些JsonDeserializer用于反序列化集合中的抽象类型。现在我有一个类型,它有一个Collection属性。我该如何指示Jackson为我反序列化嵌套的集合,而不是自己去做呢?
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?? */);
        }
    }
}

是的,在自定义反序列化器中可以从JsonParser读取嵌套对象集合。也许您甚至不需要自定义反序列化器。您能发布一个JSON示例吗?您如何区分人员类型? - Alexey Gavrilov
@AlexeyGavrilov 在我的代码中,我使用“type”属性来识别不同类型的“Person”。因此,如果一个人符合某种类型,它将由适当的反序列化器进行反序列化。 - Bart
你尝试过使用Jackson多态反序列化吗?http://wiki.fasterxml.com/JacksonPolymorphicDeserialization 。它可能消除了自定义反序列化器的需要。 - Alexey Gavrilov
没有,我会在有时间的时候看一下。谢谢你提供链接。 - Bart
1个回答

0
在这种情况下(虽然它有点老,但对某些人可能会有所帮助),您实际上拥有一个嵌套的递归对象,因此您可以简单地提取代码以在节点上反序列化一个人,并迭代他的friendNodes调用相同的函数。
类似以下内容:
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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接