我有一个类似以下的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时为杰克逊提供上述类的实例,并让杰克逊在将它设置为创建的POJO之前使用此对象获取newSystemId?
请注意,上面的JSON只是实际JSON的一小部分,因此可能包含上面数百个这样的对象。我想为每个反序列化提供一个SystemIdProvider类的新实例,因为它维护的“状态”也是基于它到目前为止遇到的systemIds。因此,每次反序列化都需要以干净状态开始。
赞赏任何意见。
答案 0 :(得分: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);
}
}
使用@JsonDeserialize
字段上的systemId
注释注册反序列化器:
@JsonDeserialize(using = SystemIdDeserializer.class)
private final long systemId;
要使SystemIdProvider
中的DeserializationContext
可用,请按照以下方式致电杰克逊的映射器:
ObjectMapper mapper = new ObjectMapper();
MyPojo deserialized = mapper.reader(MyPojo.class)
.withAttribute("systemIdProvider", new SystemIdProvider())
.readValue(json);