这是关于Jackson YAML: support for anchors and references的后续问题: 我很难理解Jackson如何处理引用(因为它们本身不存在于JSON中),所以我写了一个测试:
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.kotlin.KotlinModule
import org.junit.Test
import org.yaml.snakeyaml.Yaml
import kotlin.test.assertEquals
class YamlRefTest {
data class Item(val name: String)
data class Config(val availableItems: List<Item>,
val selectedItems: List<Item>)
@Test
fun testReferenceSnakeYaml() {
val parser = Yaml()
val test = (parser.load(testYaml)
as Map<String, Map<String, List<Map<String, String>>>>)["Config"]!!
assertEquals("test", test["availableItems"]!![0]["name"])
assertEquals("test", test["selectedItems"]!![0]["name"])
}
@Test
fun testReferenceJackson() {
val mapper = ObjectMapper(YAMLFactory())
.registerModule(KotlinModule())
.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true)
val config = mapper.readValue(testYaml, Config::class.java)
assertEquals(1, config.selectedItems.size)
assertEquals("test", config.selectedItems[0].name)
}
companion object {
val testYaml = """
Config:
availableItems:
- &a1
name: test
- &a2
name: test2
selectedItems:
- *a1
"""
}
}
第一次测试通过,第二次没有。根据我对规范的理解,如果您只使用锚点(没有合并语法),YAML将引用视为复制和粘贴。杰克逊为什么不能这样做?如果是的话,我需要做些什么才能使其发挥作用?
目前未能通过:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `undagen.YamlRefTest$Item` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('a1')
at [Source: (StringReader); line: 9, column: 9] (through reference chain: undagen.YamlRefTest$Config["selectedItems"]->java.util.ArrayList[0])
注意:涉及正确使用@JsonIdentityInfo
的答案很有用(我似乎无法理解这是如何转换为锚点的。)