当前位置: 首页 > 知识库问答 >
问题:

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

郭辉
2023-03-14

我需要将可选值从json反序列化到Kotlin中的data类,这些类具有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,Column.Databind.exc;无效定义异常:无法构造$sample的实例(不存在创建者,如默认构造):无法从[source:(String)“{”id“:”1“,”content:“某些内容”}“;行:2,Column.3]com.fasterxml.jackson.Databind.exc”的对象值(不存在委托或基于属性的创建者)反序列化。singNonDefault(BeandeSerializerBase.java:1297)位于com.fasterxml.jackson.databind.deser.BeandeSerializer.DeserializeFromoBject(BeandeSerializer.java:326)位于com.fasterxml.jackson.databind.deser.BeandeSerializer.deserializer.deserialize(159)位于com.fasterxml.jackson.databind.objectMapper._ReadMapandClose(ObjectMapper.java:4013)位于

如何让jackson使用箭头-kt中的选项类型?

共有1个答案

楚丰羽
2023-03-14

您需要注册Kotlin模块

val mapper = ObjectMapper().registerModule(KotlinModule())

这是Maven依赖项,以防您还没有它。

 类似资料:
  • 我想反序列化表单中的类: 其中文本是加密的,反序列化应该在重建TestFieldEncryptedMessage实例之前取消对值的加密。 我采用的方法非常类似于:https://github.com/codesqueak/jackson-json-crypto 也就是说,我正在构建一个扩展SimpleModule的模块: 如您所见,设置了两个修饰符:EncryptedSerializerModif

  • 我正在用Jackson反序列化在Java中进行继承实验。我有一个基类: ClassA也是抽象的 我的子类: 如果我以以下形式传入的JSON: 我得到一个错误,无法构造ClassA的实例(不存在像默认构造一样的创建者):抽象类型要么需要映射到具体类型,要么需要自定义反序列化器,要么包含我遇到的其他类型信息https://github.com/FasterXML/jackson-databind/is

  • 我得到了。了解调用相同的反序列化器。是否有一种方法可以在custome反序列化器中使用或?

  • 使用杰克逊( 数据: 数据模型: 我当前的反序列化器如下所示: 注意:我的问题被定义为Scala,但我认为Java的方法足够相似,以至于无关紧要。所以Java的答案是可以接受的。

  • I'va是一个OID接口,可以由许多具体类型实现: 现在我有一个具有两个字段的对象,一个使用抽象接口类型(OID)定义,另一个使用具体类型(MyOID)定义 我想使用jackson以不同的方式序列化/反序列化字段,无论它们是使用抽象接口类型还是具体类型定义的: 注意,被序列化,包括类型信息(多态序列化),而被序列化为文本 为此,我将OID接口注释为: 并为每个具体类型分配了类型id: 最后,对容器

  • 假设我正在为某个类编写自定义序列化,但希望使用默认方法处理其中一个字段。 那要怎么做? 序列化时,我们有。 但反序列化的相应方法是什么? 请注意以下代码: 如何实现MyOuterDeserializer?