我需要将 json 中的可选值反序列化为 Kotlin 中具有Option
类型的数据类。例子:
data class Sample(val id: Long, val content: Option<String>)
fun main() {
val mapper = ObjectMapper()
val v1 = mapper.readValue("""
{ "id": "1", "content": null }
""".trimIndent(), Sample::class.java)
val v2 = mapper.readValue("""
{ "id": "2", "content": "Some content" }
""".trimIndent(), Sample::class.java)
assert(v1.id == 1)
assert(v1.content == Option.empty())
assert(v2.id == 2)
assert(v2.content == Option.just("Some content"))
}
我正在努力为这个用例编写正确版本的反序列化器。这是我尝试过的:
class OptionDeserializer<T>(private val clazz: Class<T>) : StdDeserializer<Option<T>>(clazz) {
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Option<T> {
val value = p?.codec?.readValue(p, clazz)
return if (value == null) Option.empty() else Option.just(value)
}
}
fun main() {
val mapper = ObjectMapper()
val module = SimpleModule("Option")
module.addDeserializer(Option::class.java,
OptionDeserializer(Option::class.java))
mapper.registerModule(module)
val v1 = mapper.readValue("""
{ "id": "1", "content": "Some content" }
""".trimIndent(), Sample::class.java)
assert(v1.id == 1)
assert(v1.content == Option.just("Some content"))
}
但这不起作用并引发错误:
无法构造实例
$Sample
(没有创建者,如默认构造,存在):无法从 [Source: (String)"{ "id" : "1", "content" : "部分内容" }"; 行:2,列:3] com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造实例$Sample
(不存在像默认构造一样的创建者):无法从 [Source: (String)"{ "id" : "1", "content" : "Some content “}”;line: 2, column: 3] at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452) at com .fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028) 在 com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297) 在 com.fasterxml.jackson.databind.deser.BeanDeserializer .
如何让杰克逊使用Option
来自的类型arrow-kt
?