我使用Jackson 2.8并希望将所有标准/自定义反序列化器包装在标准包装反序列化中,以便对每个属性的每个反序列化值实例进行一些后处理。为了实现这一点,我将BeanDeserializerModifier
子类化,以便将给定属性类型的基础JsonDeserializer
和适当的JavaType
传递给StdJsonDeserializer
的子类,然后调用该基类反序列化器并对结果值实例执行各种操作。
在反序列化期间,我收到以下错误:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.lindisfarne.MundaneDataClass: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
如果没有BeanDeserializerModifier
,操作当然会正常工作 - 很明显我得到了一个不正确或不完整的反序列化器。如何获得给定类型的正确解串器?
完整的Kotlin代码重现以下问题:
package com.lindisfarne
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.*
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.fasterxml.jackson.module.kotlin.readValue
class ReferencingBeanModifier() : BeanDeserializerModifier() {
override fun modifyDeserializer(config: DeserializationConfig?, beanDesc: BeanDescription?, deserializer: JsonDeserializer<*>?): JsonDeserializer<*> {
val javaType = beanDesc?.type
return WrappingDeserializer(deserializer = deserializer, javaType = javaType)
}
}
class WrappingDeserializer(val deserializer :JsonDeserializer<*>?, val javaType: JavaType?) : StdDeserializer<Any>(javaType) {
override fun deserialize(jsonParser: JsonParser?, deserializationContext: DeserializationContext?): Any? {
val instance = deserializer?.deserialize(jsonParser,deserializationContext)
println(instance)
//do more stuff
return instance
}
}
data class MundaneDataClass(
val trivialBoolean: Boolean = true,
val borningInt:Int = 1,
val meaninglessString:String = "yes"
)
fun massiveFailure() : Unit {
val mapper = ObjectMapper()
with (mapper) {
registerModules(
KotlinModule().setDeserializerModifier(ReferencingBeanModifier())
)
disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
}
val mdc = MundaneDataClass()
val dataJson = mapper.writeValueAsString(mdc)
val mdc2 = mapper.readValue<MundaneDataClass>(dataJson)
}