问题描述
我有一个类似以下的JSON:
{
systemId: 7
name: "Phil"
data: "XYZ"
pointers: [
{
systemId: 23
name: "Peter"
},
{
systemId: 27
name: "Jeroen"
}
]
}
在上述JSON的POJO中,所有字段都是最终字段。 现在,在反序列化期间,我希望能够修改Jackson的POJO上设置的systemId字段之前。 此外,更改后的systemId实际上将由有状态对象根据JSON中的当前systemId提供。 例如,要在反序列化POJO上设置的新systemId可能由如下类的实例提供:
public class SystemIdProvider {
...
public long getNewSystemId(long oldSystemId) {
// do something with the oldSystemId and
// the current state of this object to get the newSystemId
return newSystemId;
}
}
当它反序列化JSON时,有什么方法可以向Jackson提供上述类的实例,并让Jackson在创建的POJO上设置此对象之前使用此对象获取newSystemId吗?
请注意,上面的JSON只是实际JSON的一小段,因此可能包含数百个上述对象。 我想针对每个反序列化提供一个SystemIdProvider类的NEW实例,因为它维护的“状态”也基于迄今为止所遇到的systemIds。 因此,对于每个反序列化,都需要从一个干净的状态开始。
任何输入表示赞赏。
1楼
您需要为此编写一个自定义解串器。 假设您具有以下POJO:
public class MyPojo {
private final long systemId;
private final String foo;
public MyPojo(long systemId, String foo) {
this.systemId = systemId;
this.foo = foo;
}
// getters and other methods
}
为systemId
字段编写一个自定义反序列化器:
public class SystemIdDeserializer extends StdDeserializer<Long> {
public SystemIdDeserializer() {
super(Long.class);
}
@Override
public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
SystemIdProvider systemIdProvider = (SystemIdProvider) ctxt.getAttribute("systemIdProvider");
Long oldSystemId = _parseLong(jp, ctxt);
return systemIdProvider.getNewSystemId(oldSystemId);
}
}
在systemId
字段上使用@JsonDeserialize
批注注册反序列化器:
@JsonDeserialize(using = SystemIdDeserializer.class)
private final long systemId;
为了使SystemIdProvider
在DeserializationContext
可用,请像下面这样调用Jackson的映射器:
ObjectMapper mapper = new ObjectMapper();
MyPojo deserialized = mapper.reader(MyPojo.class)
.withAttribute("systemIdProvider", new SystemIdProvider())
.readValue(json);