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);
我是 运行 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);