- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Android Studio 上使用 Jackson 和 Kotlin 解析 XML 文件。特别是,我想在 jackson-module-kotlin 中运行以下测试用例的代码:
@JacksonXmlRootElement(localName = "MyPojo")
data class MyDataPojo (
@JacksonXmlElementWrapper(localName = "elements")
@JacksonXmlProperty(localName = "element")
val elements : List<MyDataElement>
)
data class MyDataElement (
@JacksonXmlProperty(localName = "value", isAttribute = true)
var value: String
)
我正在尝试像这样解析 XML 文件:
val xmlMapper = XmlMapper().apply {
registerModule(KotlinModule())
}
val pojo = context.resources.assets.open(name).use { input ->
xmlMapper.readValue<MyDataPojo>(input)
}
失败并出现以下异常:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Invalid definition for property `elements` (of type `eu.tilk.wihajster.MyDataPojo`): Could not find creator property with name 'elements' (known Creator properties: [element])
我正在使用 Jackson 2.10.3,这是我在 build.gradle 中的依赖项部分:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.fasterxml.jackson.core:jackson-core:2.10.3'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.10.3'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.10.3'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.10.3'
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.10.3"
implementation 'javax.xml.stream:stax-api:1.0-2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
我做错了什么?此代码是从 jackson-module-kotlin 的测试中复制的,因此我相信它应该可以正常工作。
最佳答案
这是一个 open issue使用 Jackson Kotlin 模块:
apatrida commented on 14 Jul 2018
JacksonXmlElementWrapper
cannot be on a parameter therefore no property name ofelements
gets added to the creator parameter, and insteadJacksonXmlProperty
ends up on the parameter which is the wrong name. So then the mapper tries to pass inelements
but the parameter appears to be propertyelement
您链接的测试实际上预计会因数据类而失败:
@JacksonXmlRootElement(localName = "MyPojo")
data class MyDataPojo (
@JacksonXmlElementWrapper(localName = "elements")
@JacksonXmlProperty(localName = "element")
val elements : List<MyDataElement>
)
@Test
// Conflict between the annotations that is not current resolvable.
fun test_data_class() {
expectFailure<InvalidDefinitionException>("Problem with conflicting annotations related to #153 has been fixed!") {
// I create a pojo from the xml using the data classes
val pojoFromXml = mapper.readValue(xml, MyDataPojo::class.java)
// I create a xml from the pojo
val xmlFromPojo = mapper.writeValueAsString(pojoFromXml)
// I compare the original xml with the xml generated from the pojo
assertEquals(xml, xmlFromPojo)
}
}
然而,它预计适用于非数据类:
@JacksonXmlRootElement(localName = "MyPojo")
class MyPojo {
@JacksonXmlElementWrapper(localName = "elements")
@JacksonXmlProperty(localName = "element")
var list: List<MyElement>? = null
}
@Test
fun test_class() {
// I create a pojo from the xml using the standard classes
val pojoFromXml = mapper.readValue(xml, MyPojo::class.java)
// I create a xml from the pojo
val xmlFromPojo = mapper.writeValueAsString(pojoFromXml)
// I compare the original xml with the xml generated from the pojo
assertEquals(xml, xmlFromPojo)
}
如您所见——尽管 Kotlin 让它变得有点困难——不同之处在于 elements
在数据类中是一个构造函数参数,但在常规类中是一个字段。
在不创建自定义(反)序列化程序的情况下,我能想到的最佳解决方法是
lateinit var
hashCode()
、equals()
和 toString()
例如:
@JacksonXmlRootElement(localName = "MyPojo")
class WorkaroundPojo private constructor() {
constructor(list: List<MyElement>) : this() {
this.list = list
}
@JacksonXmlElementWrapper(localName = "elements")
@JacksonXmlProperty(localName = "element")
lateinit var list: List<MyElement>
private set
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as WorkaroundPojo
if (list != other.list) return false
return true
}
override fun hashCode(): Int {
return list.hashCode()
}
override fun toString(): String {
return "WorkaroundPojo(list=$list)"
}
}
@Test
fun test_workaround() {
val pojoFromXml = mapper.readValue(xml, WorkaroundPojo::class.java)
val xmlFromPojo = mapper.writeValueAsString(pojoFromXml)
assertEquals(xml, xmlFromPojo)
}
这是一个 JUnit5 测试,其中包含一个更复杂的示例,展示了如何使用 Jackson 2.13.0 将上述内容与继承、枚举等结合起来:
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.dataformat.xml.XmlMapper
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule
import com.fasterxml.jackson.module.kotlin.kotlinModule
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import javax.xml.bind.annotation.XmlEnumValue
class StackOverflow {
abstract class ActivatableElement {
abstract val active: Boolean
}
class ComplexExample private constructor(
override val active: Boolean = false,
val myEnum: MyEnum = MyEnum.First,
) : ActivatableElement() {
constructor(active: Boolean, myEnum: MyEnum, myElements: List<MyElement>) : this(active, myEnum) {
this.elements = myElements
}
@JacksonXmlElementWrapper(localName = "elementList")
@JacksonXmlProperty(localName = "element")
lateinit var elements: List<MyElement>
private set
data class MyElement(
val name: String,
val number: Int
)
enum class MyEnum {
@XmlEnumValue("First value of MyEnum")
First,
@XmlEnumValue("Second value of MyEnum")
Second,
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as ComplexExample
if (active != other.active) return false
if (myEnum != other.myEnum) return false
if (elements != other.elements) return false
return true
}
override fun hashCode(): Int {
var result = active.hashCode()
result = 31 * result + myEnum.hashCode()
result = 31 * result + elements.hashCode()
return result
}
}
val xml = """
<ComplexExample>
<active>true</active>
<myEnum>Second value of MyEnum</myEnum>
<elementList>
<element>
<name>First Item</name>
<number>1</number>
</element>
<element>
<name>Second Item</name>
<number>2</number>
</element>
<element>
<name>Third Item</name>
<number>3</number>
</element>
</elementList>
</ComplexExample>
""".trimIndent()
@Test
fun test_complex_example() {
val mapper = XmlMapper.builder()
.addModule(kotlinModule())
.addModule(JaxbAnnotationModule())
.build()
.enable(SerializationFeature.INDENT_OUTPUT)
val example = mapper.readValue(xml, ComplexExample::class.java)
val xmlFromExample = mapper.writeValueAsString(example).trim()
Assertions.assertEquals(xml, xmlFromExample)
val expected = ComplexExample(
active = true,
myEnum = ComplexExample.MyEnum.Second,
myElements = listOf(
ComplexExample.MyElement("First Item", 1),
ComplexExample.MyElement("Second Item", 2),
ComplexExample.MyElement("Third Item", 3),
)
)
Assertions.assertEquals(expected, example)
Assertions.assertEquals(expected.hashCode(), example.hashCode())
}
}
关于xml - Kotlin 上 JacksonXmlElementWrapper 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60655621/
我正在查看Kotlin Github page我注意到 Kotlin 语言本身大部分是用 Kotlin 编写的:我只是想知道,一种语言怎么可能大部分都是用它自己的语言编写的?在您可以使用正在创建的语言
我有以下非常简单的 kotlin 代码来演示中缀函数 com.lopushen.demo.presentation 包 fun main(args: Array) { print("Hello
我在 Java 中有 2 个模型类,其中一个扩展了另一个 @UseStag public class GenericMessages extends NavigationLocalizationMap
Kotlin 代码 runBlocking { flow { for (i in 0..4) { println("Emit $i")
这三个 Kotlin 插件和它们的实际作用有什么区别? plugins { id 'kotlin-android' id 'org.jetbrains.kotlin.android'
我正在为某些现有库添加 Kotlin 原生 linuxX64 目标支持。库已成功编译,但在运行测试用例时,出现以下运行时错误: kotlin.native.concurrent.InvalidMuta
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 2 年前。 Improve t
我创建了一个类并向其添加了一个与成员函数具有相同签名的扩展,并执行了这个方法,它总是执行成员方法。 class Worker { fun work() = "...working" } fun
我知道传递给函数的参数将被视为“val”,即使变量被初始化为“var”。但这对我来说一直是个问题。在下面的示例代码中,我想通过使用函数“changeNum”修改变量“num”的值。但当然,Kotlin
现在,我正在尝试用 Kotlin 重写我的 Java 应用程序。然后,我遇到了日志语句,比如 log.info("do the print thing for {}", arg); 所以我有两种方法可
有点出名article关于许多语言的异步编程模型的状态,指出它们存在“颜色”问题,特别是将生态系统分为两个独立的世界:异步和非异步。以下是这种语言的属性: 每个函数都有一种颜色,红色或蓝色(例如asy
因为 KDoc 文档生成引擎是 abandoned in favor of Dokka , Kotlin 文档应该称为“KDoc 注释”,还是“Dokka 注释”? 最佳答案 如所述here , KD
我想在可空对象上传递函数引用。以 Android 为例,假设我想使用 Activity#onBackPressed来自作为该事件的子级的片段。 如果我想调用这个函数,我可以很容易地做到 activit
我有一个列表 (x, y)其中y只能是 0 或 1 这样 例如: [(3, 0), (3, 1), (5, 1)] [(5, 0), (3, 1), (5, 1)] [(1, 1), (3, 1),
从强类型语言的定义来看: A strongly-typed programming language is one in which each type of data (such as intege
这不能编译的事实是否意味着它们不是一流的类型? fun foo(s: String): Int = s.length // This won't compile. val bar = foo 有没有办
如果在 Java i++是一个表达式和 i++;是一个表达式语句,分号(;) 在 Kotlin 中是可选的,是 i++ Kotlin 中的表达式或表达式语句? 最佳答案 i++是一个表达式,因为它有一
代码(如下所示)是否正确?它取自 Kotlin-docs.pdf 的第 63 页,这也是 https://kotlinlang.org/docs/reference/generics.html 的最后
我正在尝试使用 Kotlin 为 Android 的一些全局 API 解析器(检查网络连接、调用 API 并通过来自源的单个调用返回格式化数据),并且在某些时候我不得不创建一个通用类型 object就
kotlinlang 中的任务: 使用月份变量重写此模式,使其与格式 13 JUN 1992(两位数字、一个空格、一个月份缩写、一个空格、四位数字)中的日期相匹配。 答案是:val month = "
我是一名优秀的程序员,十分优秀!