首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在kotlin中为Arrow的选项编写自定义jackson反序列化器?

如何在kotlin中为Arrow的选项编写自定义jackson反序列化器?
EN

Stack Overflow用户
提问于 2019-10-06 12:13:54
回答 2查看 2.9K关注 0票数 0

我需要将可选值从json反序列化到具有Option类型的Kotlin数据类。示例:

代码语言:javascript
复制
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"))
}

我很难为这个用例编写反序列化器的正确版本。以下是我尝试过的:

代码语言:javascript
复制
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-ktarrow-kt类型

EN

回答 2

Stack Overflow用户

发布于 2020-02-12 23:05:05

你需要注册Kotlin模块

代码语言:javascript
复制
val mapper = ObjectMapper().registerModule(KotlinModule())

下面是Maven依赖项,万一你还没拿到呢。

票数 1
EN

Stack Overflow用户

发布于 2021-08-16 17:31:25

另一个选项是使用自定义序列化程序。在这种情况下,没有必要明确注册任何内容。参见建议使用这里

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58257121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档