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

问题描述 投票:0回答:1

我正在用Jackson 2.10.3运行Spring Boot。

<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
java jackson deserialization json-deserialization jackson2
1个回答
0
投票

深入研究覆盖映射器和解串器,简单地做

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);
© www.soinside.com 2019 - 2024. All rights reserved.