Java 使用带有Jackson的ReferenceTypeDeserializer反序列化泛型类型&;春天

Java 使用带有Jackson的ReferenceTypeDeserializer反序列化泛型类型&;春天,java,json,serialization,kotlin,jackson,Java,Json,Serialization,Kotlin,Jackson,我想我在这里遗漏了一些明显的东西,但我似乎无法使用Spring/Kotlin/Jackson反序列化一个简单的通用容器 所讨论的数据类型非常简单: @JsonDeserialize(using = PatchableDeserializer::class) sealed class Patchable<T> { class Undefined<T>: Patchable<T>() class Null<T>: Patchable&l

我想我在这里遗漏了一些明显的东西,但我似乎无法使用Spring/Kotlin/Jackson反序列化一个简单的通用容器

所讨论的数据类型非常简单:

@JsonDeserialize(using = PatchableDeserializer::class)
sealed class Patchable<T> {
    class Undefined<T>: Patchable<T>()
    class Null<T>: Patchable<T>()
    data class Present<T>(val content: T): Patchable<T>()
    // …
}
我假设Jackson会在这里填写
PatchableDeserializer
的构造函数参数。然而,情况似乎并非如此:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'my.namespace.PatchableDeserializer': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.fasterxml.jackson.databind.JavaType' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
我假设Jackson提供了
javaType
的值,因为我在编译时无法知道它

下面是我用来测试的代码,它生成上述异常:

@RunWith(SpringRunner::class)
@JsonTest
class PatchableTest {
    @Autowired
    lateinit var objectMapper: ObjectMapper

    @Test
    fun patchableDeserialisesStringValue() {
        val value: Patchable<String> = objectMapper.readValue("\"null\"", object: TypeReference<Patchable<String>>() {})
        assertTrue(value.isPresent())
        assertEquals("null", value.unsafeGetValue())
    }
}
@RunWith(SpringRunner::class)
@JsonTest
类补丁测试{
@自动连线
lateinit var对象映射器:对象映射器
@试验
有趣的PatchableDeserialiseStringValue(){
val值:Patchable=objectMapper.readValue(“\'null\”,对象:TypeReference(){})
assertTrue(value.isPresent())
assertEquals(“null”,value.unsafeGetValue())
}
}

我错过了什么?另外,我在网上很难找到一些关于如何反序列化泛型类型的信息,所以如果有人能为泛型类型编写自定义反序列化程序,我会非常感激。

我最终为反序列化程序实现了一个不同的接口

class PatchableDeserializer(private val valueType: Class<*>?): JsonDeserializer<Patchable<*>>(), ContextualDeserializer {
    override fun createContextual(ctxt: DeserializationContext?, property: BeanProperty?): JsonDeserializer<*> {
        val wrapperType = property?.type

        val rawClass = wrapperType?.containedType(0)?.rawClass
        return PatchableDeserializer(rawClass)
    }

    override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Patchable<*> =
        Patchable.of(p!!.readValueAs(valueType))

    override fun getNullValue(ctxt: DeserializationContext?): Patchable<Any> =
            if (ctxt?.parser?.currentToken == JsonToken.VALUE_NULL)
                Patchable.ofNull()
            else
                Patchable.undefined()
}
类PatchableDeserializer(private val valueType:class?):JsonDeserializer(),ContextualDeserializer{
重写fun CreateContextent(ctxt:DeserializationContext?,属性:BeanProperty?):JsonDeserializer{
val wrapperType=属性?.type
val rawClass=包装器类型?.containedType(0)?.rawClass
返回PatchableDeserializer(rawClass)
}
重写有趣的反序列化(p:JsonParser?,ctxt:DeserializationContext?):可修补=
可修补的.of(p!!.readValueAs(valueType))
重写fun getNullValue(ctxt:DeserializationContext?):可修补=
if(ctxt?.parser?.currentToken==JsonToken.VALUE\u NULL)
可修补的
其他的
可修补。未定义()
}
这可以按预期工作,但Jackson需要解析器中的上下文信息才能工作,即上述测试代码无法工作。但是,如果显式指定要反序列化到的DTO,并且该DTO具有正确的类型注释,则它确实可以工作

class PatchableDeserializer(private val valueType: Class<*>?): JsonDeserializer<Patchable<*>>(), ContextualDeserializer {
    override fun createContextual(ctxt: DeserializationContext?, property: BeanProperty?): JsonDeserializer<*> {
        val wrapperType = property?.type

        val rawClass = wrapperType?.containedType(0)?.rawClass
        return PatchableDeserializer(rawClass)
    }

    override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Patchable<*> =
        Patchable.of(p!!.readValueAs(valueType))

    override fun getNullValue(ctxt: DeserializationContext?): Patchable<Any> =
            if (ctxt?.parser?.currentToken == JsonToken.VALUE_NULL)
                Patchable.ofNull()
            else
                Patchable.undefined()
}