Jackson MyCustomDeserializer super.deserialize(parser, dc, intoValue);不工作

Jackson MyCustomDeserializer super.deserialize(parser, dc, intoValue); not working

我是 运行 Spring 使用 Jackson 2.10.3 启动。

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.10.3</version>
</dependency>      
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.10.3</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.10.3</version>
</dependency>

我的输入值是一个 json 序列化对象的表示,在我的例子中 FC.java 创建映射器时,会注册一个新的 CustomerFCDeserializer。

  mapper = new ObjectMapper();
  SimpleModule module = new SimpleModule();
  module.addDeserializer(FC.class, new CustomFCDeserializer(fcFactory));
  mapper.registerModule(module);

CustomFCDeserializer 用于初始化序列化对象应反序列化到的 FC 对象。 fc = super.deserialize(parser, dc, fc);

通常我会反序列化它,但在这种特定情况下,无法调用默认构造函数,相反,该对象需要 FcFactory 完成的一些其他初始化。这样也可以在工厂返回的对象中设置序列化字段。

public class CustomFCDeserializer extends StdDeserializer<FC> {
    private final FCFactory fcFactory;

    public CustomFCDeserializer(FCFactory fcFactory) {
        super(FC.class);
        this.fcFactory = fcFactory;
    }

    @Override
    public FC deserialize(JsonParser parser, DeserializationContext dc) throws IOException, JsonProcessingException {
        ObjectCodec codec = parser.getCodec();
        JsonNode node = codec.readTree(parser);
        JsonNode idNode = node.get("id");
        long id = idNode.asLong(0);
        FC fc = fcFactory.getFCById(id); //<!--- create my object
        //set values on prev created fc object
        fc = super.deserialize(parser, dc, fc); //<!-- pollute it 
        return fc;
    }
}

运行 此示例将递归调用反序列化,super.deserialize 最后再次反序列化,但由于结构更改而失败。

java.lang.NullPointerException: null
    at objectMapper.CustomFcDeserializer.deserialize(CustomFcDeserializer.java:38) ~[classes/:na]
    at objectMapper.CustomFcDeserializer.deserialize(CustomFcDeserializer.java:16) ~[classes/:na]
    at com.fasterxml.jackson.databind.JsonDeserializer.deserialize(JsonDeserializer.java:129) ~[jackson-databind-2.9.0.jar:2.9.0]
    at objectMapper.CustomFcDeserializer.deserialize(CustomFcDeserializer.java:51) ~[classes/:na]
    at objectMapper.CustomFcDeserializer.deserialize(CustomFcDeserializer.java:16) ~[classes/:na]
[...]

有没有比通过一堆 if 语句处理这个问题更好的方法? 还是污染现有物体的更智能方式? deserialize(JsonParser p, DeserializationContext ctxt, T intoValue) 似乎很好,因为它需要一个 intoValue,但我正在反序列化对象,而不是集合或映射。顺便说一句,我的对象不是也没有不可变成员。

com.​fasterxml.​jackson.​databind.​JsonDeserializer
public T deserialize(JsonParser p, DeserializationContext ctxt, T intoValue) throws IOException
Alternate deserialization method (compared to the most commonly used, deserialize(JsonParser, DeserializationContext)), which takes in initialized value instance, to be configured and/or populated by deserializer. Method is not necessarily used (or supported) by all types (it will not work for immutable types, for obvious reasons): most commonly it is used for Collections and Maps. It may be used both with "updating readers" (for POJOs) and when Collections and Maps use "getter as setter".
Throws: IOException

深入研究覆盖映射器和反序列化器, 简单地做

Map<String, Object> fcInput = dfe.getArgument("fcInput");
FC fcInput = mapper.convertValue(fcInput, FC.class);
String fcString = mapper.writeValueAsString(fcInput);

long fcId = fcInput.getId();
FC existingFc = fcFactory.getFC(fcId);

ObjectMapper om = new ObjectMapper();
ObjectReader or = om.readerForUpdating(existingFc);
FC updatedFc = or.readValue(fcString);