Jackson YAML:解析锚点和引用

时间:2018-03-15 19:33:10

标签: jackson kotlin yaml

这是关于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的答案很有用(我似乎无法理解这是如何转换为锚点的。)

0 个答案:

没有答案