我正在尝试实现自定义反序列化器。 因为我只想向默认的反序列化器添加功能,所以我尝试在我的自定义反序列化器中存储默认的反序列化器:我想使用默认值来反序列化json,然后添加其他信息。
我正在尝试使用BeanDeserializerModifier来注册自定义反序列化器。
SimpleModule module = new SimpleModule("ModelModule", Version.unknownVersion());
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
JsonDeserializer<?> configuredDeserializer = super.modifyDeserializer(config, beanDesc, deserializer);
if (Document.class.isAssignableFrom(beanDesc.getBeanClass())) {
logger.debug("Returning custom deserializer for documents");
configuredDeserializer = new DocumentDeserializer(configuredDeserializer, (Class<Document>)beanDesc.getBeanClass());
}
return configuredDeserializer;
}
});
如您所见,如果要生成的对象是&#34; Document&#34;,我正在修改反序列化器,返回自定义反序列化器。我将默认的反序列化器传递给构造函数,以便以后可以使用它。
当我尝试反序列化时,杰克逊因错误而失败:
No _valueDeserializer assigned(..)
我已经调查过,似乎默认的反序列化器没有为其属性提供正确的反序列化器:对于所有属性,它使用的是反序列化器FailingDeserializer,当然,它会失败并返回上面提到的错误。这个反序列化器应该被替换,但它不是。
看来,在调用方法modifyDeserializer之后,Jackson完成了配置。
我使用的自定义反序列化器是:
@SuppressWarnings("serial")
public class DocumentDeserializer extends StdDeserializer<Document> {
private JsonDeserializer<?> defaultDeserializer;
private DocumentDeserializer(JsonDeserializer<?> defaultDeserializer, Class<? extends Document> clazz) {
super(clazz);
this.defaultDeserializer = defaultDeserializer;
}
@Override
public Document deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Document documentDeserialized = (Document) defaultDeserializer.deserialize(jp, ctxt);
/* I want to modify the documentDeserialized before returning it */
return documentDeserialized;
}
}
更新 我使用不同的反序列化器解决了这个问题:
public class CustomDeserializerModifier extends BeanDeserializerModifier {
private static final Logger logger = Logger.getLogger(CustomDeserializerModifier.class);
public CustomDeserializerModifier (Factory factory) {
this.factory = factory;
}
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
JsonDeserializer<?> configuredDeserializer;
if (CustomDeserializedNode.class.isAssignableFrom(beanDesc.getBeanClass())) {
Converter<Object, Object> conv = beanDesc.findDeserializationConverter();
JavaType delegateType = conv.getInputType(config.getTypeFactory());
configuredDeserializer = new CustomDeserializedNodeDeserializer(conv, delegateType, (JsonDeserializer<Document>) deserializer,
(Class<? extends CustomDocument<?>>)beanDesc.getBeanClass());
} else {
configuredDeserializer = super.modifyDeserializer(config, beanDesc, deserializer);
}
return configuredDeserializer;
}
@SuppressWarnings("serial")
public class CustomDeserializedNodeDeserializer extends StdDelegatingDeserializer<Object> {
private Class<? extends CustomDocument<?>> beanClass;
public CustomDeserializedNodeDeserializer(Converter<Object,Object> converter,
JavaType delegateType, JsonDeserializer<Document> delegateDeserializer, Class<? extends CustomDocument<?>> beanClass) {
super(converter, delegateType, delegateDeserializer);
this.beanClass = beanClass;
}
@Override
public CustomDeserializedNode deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
CustomDeserializedNode node = (CustomDeserializedNode)factory.createCustomDocument(beanClass);
CustomDeserializedNode documentDeserialized = (Document) super.deserialize(jp, ctxt, node);
return documentDeserialized;
}
}
}
可能会扩展StdDelegatingDeserializer来执行@StaxMan的建议。
答案 0 :(得分:3)
这应该添加到FAQ中,但您需要做的是实现2个接口:
ResolvableDeserializer
(方法resolve(...)
)ContextualDeserializer
(方法createContextual(...)
)并将这些调用委托给defaultDeserializer
,以防它实现一个或两个接口。这些是解串器初始化所必需的;特别是ContextualDeserializer
,通过它可以为反序列化器提供属性注释。
ResolvableDeserializer
使用BeanDeserializer
来获取其拥有的属性的反序列化程序(如果有);这是可能会提到_valueDeserializer
的地方。