How use jackson ObjectMapper inside custom deserializer?

前端 未结 3 549
野性不改
野性不改 2020-12-31 02:56

I try to write custom jackson deserializer. I want \"look\" at one field and perform auto deserialization to class, see example below:

import com.fasterxml.j         


        
3条回答
  •  被撕碎了的回忆
    2020-12-31 03:17

    The immediate problem seems to be that the @JsonDeserialize(using=...) is being picked up for your implementations of MyInterface as well as MyInterface itself: hence the endless loop.

    You can fix this my overriding the setting in each implementation:

    @JsonDeserialize(using=JsonDeserializer.None.class)
    public static class MySuccess implements MyInterface {
    }
    

    Or by using a module instead of an annotation to configure the deserialization (and removing the annotation from MyInterface):

    mapper.registerModule(new SimpleModule() {{
        addDeserializer(MyInterface.class, new MyDeserializer());
    }});
    

    On a side-note, you might also consider extending StdNodeBasedDeserializer to implement deserialization based on JsonNode. For example:

    @Override
    public MyInterface convert(JsonNode root, DeserializationContext ctxt) throws IOException {
        java.lang.reflect.Type targetType;
        if (root.has("custom_field")) {
            targetType = MyFailure.class;
        } else {
            targetType = MySuccess.class;
        }
        JavaType jacksonType = ctxt.getTypeFactory().constructType(targetType);
        JsonDeserializer deserializer = ctxt.findRootValueDeserializer(jacksonType);
        JsonParser nodeParser = root.traverse(ctxt.getParser().getCodec());
        nodeParser.nextToken();
        return (MyInterface) deserializer.deserialize(nodeParser, ctxt);
    }
    

    There are a bunch of improvements to make to this custom deserializer, especially regarding tracking the context of the deserialization etc., but this should provide the functionality you're asking for.

提交回复
热议问题