Kotlin中的Jackson:XML重复元素的序列化与反序列化
我正在尝试把如下的XML文档序列化/反序列化到Kotlin数据类中:
<doc>
<id>123</id>
<items>
<item><c>A</c><v>1</v></item>
<item><c>B</c><v>2</v></item>
</items>
<doc>
数据类看起来像这样:
@JacksonXmlRootElement(localName = "doc")
data class Doc(
@JacksonXmlProperty(localName = "id")
val id: String,
@JacksonXmlElementWrapper (localName = "items")
@JacksonXmlProperty(localName = "item")
val iList: List<Item>
)
data class Item (
@JacksonXmlProperty(localName = "c")
val code: String,
@JacksonXmlProperty(localName = "v")
val value: String
)
在从POST请求反序列化时,使用默认的Jackson 3.1.2会得到如下结果(取自实际运行,因此实际的项和类名已用示例替换):
...exception [Request processing failed: org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class Doc]] with root cause
tools.jackson.databind.exc.InvalidDefinitionException: Invalid definition for property 'types' (of type `Doc`): Could not find creator property with name 'types' (known Creator properties: [...(skipped)])
at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 1]
at tools.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:60) ~[jackson-databind-3.1.2.jar:3.1.2]
我阅读了 Jackson deserialization of list of objects with kotlin 和 FasterXML/jackson-module-kotlin#153。看起来仍然没有好的解决方案。我尝试了最新的Jackson版本3.2.0。那个jackson-bom:3.2.0仍然包含3.1.2的部分,所以我强制包含了3.2.0:
implementation("tools.jackson.module:jackson-module-kotlin:3.2.0")
implementation("tools.jackson.core:jackson-core:3.2.0")
implementation("tools.jackson.core:jackson-databind:3.2.0")
implementation("tools.jackson.dataformat:jackson-dataformat-xml:3.2.0")
implementation("tools.jackson.dataformat:jackson-dataformat-properties") // 2.x should be used for jackson-3 according to the documentation
结果是能够进行反序列化。但序列化失败,显示为
... exception [Handler dispatch failed: java.lang.NoClassDefFoundError: com/fasterxml/jackson/annotation/JsonApplyView] with root cause
java.lang.ClassNotFoundException: com.fasterxml.jackson.annotation.JsonApplyView
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526) ~[na:na]
at tools.jackson.databind.introspect.JacksonAnnotationIntrospector.findApplyView(JacksonAnnotationIntrospector.java:556) ~[jackson-databind-3.2.0.jar:3.2.0]
很可能是Jackson各部分版本不匹配。那3.2.0怎么了?还没准备好吗?
进一步深入后编辑:我尝试了 Using Jackson to parse XML with repeated element 中的一个方案,因此数据类改为:
@JacksonXmlRootElement(localName = "doc")
data class Doc(
@JacksonXmlProperty(localName = "id")
val id: String,
@JacksonXmlElementWrapper (localName = "items")
@JacksonXmlProperty(localName = "items")
val iList: List<Item>
) {
@JacksonXmlRootElement(localName = "item")
data class Item (
@JacksonXmlProperty(localName = "c")
val code: String,
@JacksonXmlProperty(localName = "v")
val value: String
)
}
是的,反序列化工作,但使用3.1.2进行序列化时结果很糟糕
<doc>
<id>123</id>
<items>
<items><item><c>A</c><v>1</v></item></items>
<items><item><c>B</c><v>2</v></item></items>
</items>
<doc>
解决方案
嗯,看起来Jackson对于处理XML来说不是一个好选择(至少对我而言是这样),那就转向kotlinx.serialization和 xmlutil
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。