我正在用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
深入研究覆盖映射器和解串器,简单地做
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);