[英]Jackson Custom Serializer simplification
I have a payload like this:我有这样的有效载荷:
items: [
{
"foo" : "baz",
"whatever" : "thing"
}
]
Literally, all I have to do is just navigate to /items/0
and then continue the normal deserialization process.从字面上看,我所要做的就是导航到
/items/0
,然后继续正常的反序列化过程。 But I don't see how I can do that with the current JsonDeserializer.但是我不知道如何使用当前的 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)
}
}
Once I navigate properly, I don't see anyway to thus "continue".一旦我正确导航,无论如何我都看不到“继续”。 I have gone so far as to instantiate another
ObjectMapper
to do the job, but this doesn't work either because I have the deserializer directly on my Bug
class, so it gets invoked twice.我什至实例化了另一个
ObjectMapper
来完成这项工作,但这也不起作用,因为我直接在我的Bug
class 上安装了反序列化器,所以它被调用了两次。
How do I simply deserialize normally, once I've navigated to the correct json path?一旦我导航到正确的 json 路径,我该如何简单地正常反序列化?
If you have an input {"items": [{"foo": "baz","whatever": "thing"}]}
json file and you want to deserialize it to a Bug
list where Bug
class is like data class Bug(var foo: String, var whatever: String)
you can use TypeReference
to instantiate reference to the generic type List<Bug>
like below:如果你有一个输入
{"items": [{"foo": "baz","whatever": "thing"}]}
json 文件,你想将它反序列化到一个Bug
列表,其中Bug
class 就像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>>(){})
}
To override custom deserialiser and provide your own you need to use BeanDeserializerModifier
.要覆盖自定义反序列化器并提供您自己的反序列化器,您需要使用
BeanDeserializerModifier
。 You can find example here:你可以在这里找到例子:
Also you can implement a new custom deserialiser, skip the beginning of JSON
payload, deserialise to an inner class and return what you want.您还可以实现一个新的自定义反序列化器,跳过
JSON
有效负载的开头,反序列化为内部 class 并返回您想要的内容。 It could look like below:它可能如下所示:
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
)
}
You need to register above deserializer:您需要在反序列化器上方注册:
@JsonDeserialize(using = BugJsonDeserializer::class)
data class Bug(
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.