修正的类型参数会导致Jackson为通用参数而不是实际类型的对象返回LinkedHashMaps

问题描述

上下文

在我的Web应用程序中,我正在向API发送请求,该API返回分页的响应。为了坚持DRY原则,我决定使用通用的Page类和通用方法来处理常见的操作,例如获取一个n项目。这导致我发现以下问题,为此我构建了最小的复制器。

复制者

@SpringBoottest
class JacksonProblemReproducer {
    data class Page<T>(
            val items: List<T>,val limit: Int
    )

    data class SomeItem(
            val name: String,val price: Int
    )

    private val testJSON = """
{
    "items": [
    {
        "name": "item1","price": 5
    }
    ],"limit": 10
}
"""

    private inline fun <reified InnerType> getPage() : Page<InnerType> {
        return jacksonObjectMapper().readValue<Page<InnerType>>(testJSON)
    }


    @Test
    fun jacksonProblemReproducer() {
        val directlyDeserializedPage = jacksonObjectMapper().readValue<Page<SomeItem>>(testJSON)

        assertTrue("Directly deserialized Page limit was not 10",directlyDeserializedPage.limit == 10)
        assertTrue("Directly deserialized item1 has the correct name",directlyDeserializedPage.items[0].name == "item1")

        val indirectlyDeserializedPage = getPage<SomeItem>()

        assertTrue("Indirectly deserialized Page limit was not 10",indirectlyDeserializedPage.limit == 10)
        // Fails with ClassCastException
        assertTrue("Indirectly deserialized item1 has the correct name",indirectlyDeserializedPage.items[0].name == "item1")
    }

}

最后一个断言以ClassCastException失败,因为无法将LinkedHashMap强制转换为SomeItem,而且由于我理解{{1 }}和reified,这意味着该函数已插入到调用站点,因此,这应该完全等同于我对inline的直接调用,但仍然可以正常工作,而另一个则不能。

任何帮助都将受到高度赞赏,因为我已经为此努力了一段时间:)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...