kotlin Jackson自定义串行器简化

f0ofjuux  于 2022-12-30  发布在  Kotlin
关注(0)|答案(2)|浏览(134)

我有一个这样的载荷:

items: [
{
   "foo" : "baz",
   "whatever" : "thing"
}
]

从字面上讲,我所要做的就是导航到/items/0,然后继续正常的反序列化过程,但我不知道如何使用当前的JsonDeserializer来完成这一过程。

class BugDeserializer : JsonDeserializer<Bug>() {
    override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Bug {
        val node: TreeNode = p!!.readValueAsTree()

        val correct = node.at("/items/0")
        
        // Now what? 'correct' has no `readValueAs` method
        return p.readValueAs(Bug::class.java)

    }
}

一旦我正确地导航,我就不会看到任何“继续”的东西,我甚至示例化了另一个ObjectMapper来完成这项工作,但这也不起作用,因为我的Bug类上直接有反序列化器,所以它被调用了两次。
一旦我导航到正确的json路径,我如何简单地进行正常的反序列化?

1sbrub3j

1sbrub3j1#

要覆盖自定义反序列化器并提供自己的反序列化器,您需要使用BeanDeserializerModifier。您可以在此处找到示例:

你也可以实现一个新的自定义反序列化器,跳过JSON有效载荷的开头,反序列化到一个内部类并返回你想要的。

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JavaType
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.type.SimpleType

class BugJsonDeserializer : JsonDeserializer<Bug>() {

    private val innerBugType: JavaType = SimpleType.constructUnsafe(InnerBug::class.java)

    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Bug {
        p.nextToken() // start object
        p.nextToken() // field name
        p.nextToken() // start array

        val innerDeser: JsonDeserializer<*> = ctxt.findNonContextualValueDeserializer(innerBugType)
        val (foo, whatever) = innerDeser.deserialize(p, ctxt) as InnerBug

        return Bug(foo, whatever)
    }

    private data class InnerBug(
        val foo: String? = null,
        val whatever: String? = null
    )
}

您需要注册上述解串器:

@JsonDeserialize(using = BugJsonDeserializer::class)
data class Bug(
...

另见:

t30tvxxf

t30tvxxf2#

如果您有一个输入{"items": [{"foo" : "baz","whatever" : "thing"}]} json文件,并且您希望将其反序列化为Bug列表,其中Bug类类似于data class Bug(var foo: String, var whatever: String),则可以使用TypeReference示例化对泛型类型List<Bug>的引用,如下所示:

data class Bug(var foo: String, var whatever: String)

fun main() {
    val mapper = ObjectMapper().registerKotlinModule()
    val json = """
       {"items": [
        {
           "foo" : "baz",
           "whatever" : "thing"
        }
        ]}
    """.trimIndent()

    val items: JsonNode = mapper.readTree(json).get("items")
    val bugs: List<Bug> = mapper.convertValue(items, object: TypeReference<List<Bug>>(){})
}
  • Edit*:使用com.fasterxml.jackson.module.kotlin.readValue可以获得一个将json数组转换为Array<Bug>对象的更简单的解决方案:
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue

fun main() {
    val mapper = jacksonObjectMapper()
    val json = """
       {"items": [
        {
           "foo" : "baz",
           "whatever" : "thing"
        }
        ]}
    """.trimIndent()
    val items: JsonNode = mapper.readTree(json).get("items")
    val bugs = mapper.readValue<Array<Bug>>(items.toPrettyString())  
}

相关问题