我正在尝试实现一个Jackson Deserializer,以便在它们发生变化时有一种迁移JSON的方式(例如,重命名的字段,我需要将现在不一致的JSON读取为一致的JSON)。
这样做的一种方法是创建一个JsonDeserializer,将JSON读作正确的最终类,然后再将其作为MAP读取,以便选择更改。
我似乎无法这样做,因为每次我读取或反序列化JSON时,后备流都会关闭。
class CustomDeserializer extends StdDeserializer<MyPOJO> implements ResolvableDeserializer{
private final JsonDeserializer<?> deserializer;
private final ObjectMapper mapper;
public CustomDeserializer(JsonDeserializer<?> deserializer, ObjectMapper mapper) {
super(MyPOJO.class);
this.deserializer = deserializer;
this.mapper = mapper;
}
@Override
public MyPOJO deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
MyPOJO deserialized = (MyPOJO) deserializer.deserialize(jp, ctxt);
// Custom migration would go here...
return deserialized;
}
@Override
public void resolve(DeserializationContext ctxt) throws JsonMappingException {
((ResolvableDeserializer) deserializer).resolve(ctxt);
}
}
我正在避免创建新的ObjectMapper,因为已经有一个定制的,有自定义的日期反序列化器,所以当我使用MyPOJO自定义反序列化器时,我希望能够以某种方式委托反序列化,以便它使用以前的所有配置。
答案 0 :(得分:0)
这就是我提出的:
@Autowired
public Serializer(List<IDeserializer> deserializers) {
SimpleModule module = new SimpleModule("name");
registerDeserializers(module, deserializers);
mapper.registerModule(module);
mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
}
private void registerDeserializers(SimpleModule module, List<IDeserializer> deserializers) {
if (CollectionUtils.isNotEmpty(deserializers)) {
final Map<Class<?>, IDeserializer> deserializerRegistryMap = toMap(deserializers);
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (deserializerRegistryMap.containsKey(beanDesc.getBeanClass())){
return deserializerRegistryMap.get(beanDesc.getBeanClass()).getDeserializer(mapper);
}
return super.modifyDeserializer(config, beanDesc, deserializer);
}
});
}
}
@Component
public class MigrationDeserializer {
@Autowired
private MigratorRegistry migratorRegistry;
public <T> JsonDeserializer<T> createDeserializer(final ObjectMapper mapper, final Class<T> returnType, final Class<? extends SerializedObjectsHistory<T>> historyType){
return new StdDeserializer<T>(returnType){
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
SerializedObjectsHistory<T> history = mapper.readValue(p, historyType);
return migratorRegistry.migrate(history, returnType);
}
};
}
}
在序列化程序中,我将我的POJO反序列化为“HistoryPOJO”,这与我的POJO基本相同,但包含所有字段,甚至删除/重命名的字段。
然后我将其转换为当前版本。