我有一个类似以下的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。因此,对于每个反序列化,都需要从一个干净的状态开始。
任何输入表示赞赏。
最佳答案
您需要为此编写一个自定义解串器。假设您具有以下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
中可用,请像这样调用Jackson的映射器:ObjectMapper mapper = new ObjectMapper();
MyPojo deserialized = mapper.reader(MyPojo.class)
.withAttribute("systemIdProvider", new SystemIdProvider())
.readValue(json);
关于java - jackson 状态反序列化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31635581/