我需要将可选值从json反序列化到具有Option类型的Kotlin数据类。示例:
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实例(与默认构造一样,不存在):不能从源代码的对象值(没有委托或基于属性的Creator)反序列化:(String)"{ "id“:"1","content”:“Source”};行: 2,列:3 com.fasterxml.jackson.databind.exc.InvalidDefinitionException:不能构造$Sample的实例(没有创建者,像默认的构造一样,存在):不能从对象值(没有委托或基于属性的创建者)反序列化:(字符串)“{”id:"1",“内容”:“一些内容”};线路: 2,专栏:3在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) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)在com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
如何让杰克逊使用来自arrow-kt的arrow-kt类型
发布于 2020-02-12 23:05:05
发布于 2021-08-16 17:31:25
另一个选项是使用自定义序列化程序。在这种情况下,没有必要明确注册任何内容。参见建议使用这里。
https://stackoverflow.com/questions/58257121
复制相似问题