java - 通过 Kotlin 使用 Jackson 反序列化对象列表

标签 java kotlin jackson

我正在尝试通过 Kotlin 使用 Jackson 来反序列化由 lastfm api 提供的 xml。我在 Java 中使用 JAXB 进行了此工作,并且正在尝试移植它。除了未包装的列表字段外,一切正常 - 下面示例中的 Track。我知道 Track 数据类正在工作,因为如果我使用 val track: Track? = null而不是val track: List<Track>? = null我确实得到了一个有效的单个 Track 对象。

我得到的错误是 com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of info.eidson.lastfm.Track (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Flash \Flash Gordon's Theme\&quot;&quot;') at [Source: (ByteArrayInputStream); line: 1, column: 205] (through reference chain: info.eidson.lastfm.RecentTracks["track"]->java.util.ArrayList[1])我相信它正在尝试使用 List 类作为 POJO 而不是 Track。

我尝试使用常规类而不是具有相同结果的数据类。根据https://www.baeldung.com/jackson-xml-serialization-and-deserialization所需要做的就是添加 @JacksonXmlElementWrapper(useWrapping = false)注解。我尝试过使用和不使用 @JacksoXmlProperty注释,我尝试设置 useWrapping在映射器上。

接下来我应该尝试什么?

object Api {

    fun getRecentTracks(): RecentTracks {
        val module = JacksonXmlModule()
        module.setDefaultUseWrapper(false);
        val xmlMapper = XmlMapper(module)
        xmlMapper.registerKotlinModule()
        xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        xmlMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
        val params = HashMap<String?, String?>()
        params.put("user", "eidsonator")

        val out = Http.getRequest("user.getrecenttracks", params)
        val stream =  ByteArrayInputStream(out.toByteArray())
        return xmlMapper.readValue(stream, RecentTracks::class.java)
    }
}

data class RecentTracks(
    val user: String = "",
    val page: Int = -1,
    val perPage: Int = -1,
    val totalPages: Int = -1,
    val total: Int = -1,
    @JacksonXmlProperty(localName = "track") 
    @JacksonXmlElementWrapper(useWrapping = false)
    val track: List<Track>? = null
)

data class Track(
    val name: String = "",
    val artist: String = "",
    val album: String = ""
)

<?xml version="1.0" encoding="UTF-8"?>
<recenttracks page="1" perPage="50" total="283105" totalPages="5663" user="eidsonator">
    <track>
        <artist mbid="">Rockit</artist>
        <name>Flash \Flash Gordon's Theme\&quot;&quot;</name>
        <streamable>0</streamable>
        <mbid/>
        <album mbid="">Freddie Mercury Rework</album>
        <url>https://www.last.fm/music/Rockit/_/Flash+%5CFlash+Gordon%27s+Theme%5C%22%22</url>
        <image size="small">https://lastfm.freetls.fastly.net/i/u/34s/2a96cbd8b46e442fc41c2b86b821562f.png</image>
        <image size="medium">https://lastfm.freetls.fastly.net/i/u/64s/2a96cbd8b46e442fc41c2b86b821562f.png</image>
        <image size="large">https://lastfm.freetls.fastly.net/i/u/174s/2a96cbd8b46e442fc41c2b86b821562f.png</image>
        <image size="extralarge">https://lastfm.freetls.fastly.net/i/u/300x300/2a96cbd8b46e442fc41c2b86b821562f.png</image>
        <date uts="1578532113">09 Jan 2020, 01:08</date>
    </track>
    <track>
        <artist mbid="">A June &amp; J Beat</artist>
        <name>Irony</name>
        <streamable>0</streamable>
        <mbid>fa542ad6-ed2f-4ce6-ab4c-b2671cd916fa</mbid>
        <album mbid="">Appetizers (Chillhop Presents)</album>
        <url>https://www.last.fm/music/A+June+&amp;+J+Beat/_/Irony</url>
        <image size="small">https://lastfm.freetls.fastly.net/i/u/34s/6aded46748a466920f12854069d9226e.jpg</image>
        <image size="medium">https://lastfm.freetls.fastly.net/i/u/64s/6aded46748a466920f12854069d9226e.jpg</image>
        <image size="large">https://lastfm.freetls.fastly.net/i/u/174s/6aded46748a466920f12854069d9226e.jpg</image>
        <image size="extralarge">https://lastfm.freetls.fastly.net/i/u/300x300/6aded46748a466920f12854069d9226e.jpg</image>
        <date uts="1578531592">09 Jan 2020, 00:59</date>
    </track>
    <!-- 48 more tracks...   -->
</recenttracks>

最佳答案

问题似乎是由您尝试获取此 XML 引起的:

<artist mbid="">Rockit</artist>

并将其反序列化为名为 artist 的单个字符串属性。 专辑也是如此。 name 没问题,因为它没有 mbid 属性,但由于 artistalbum 具有该属性,Jackson 无法直接将该 XML 元素反序列化为字符串,因为它不知道如何处理 mbid。 (您可以通过删除 mbid 属性来检查这一点:一旦我这样做,反序列化就起作用了。)

Track 上的 artistalbum 属性是否应该是对象本身,其中一个属性为 mbid ,另一个属性为 mbid也许是文本的属性?

关于java - 通过 Kotlin 使用 Jackson 反序列化对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59664808/

相关文章:

java - 如何将 "todate picker"选定日期设置为 "from datepicker"日期的最大日期

kotlin - 取字符串(如果不为空则无法按预期工作)

java - 如何在 JSON 中存储键值对以在 Java 中反序列化?

spring - Jackson 在 Spring Boot Rest 应用程序中将日期更改为 1 天。

java - 在 Java 中,我们可以声明 lambda 表达式存储在堆中吗?

java - OSGi 与 JPA : Service not starting although code seems ok

java - spring hibernate对内存消耗的影响比纯jsp/servlet多少?

date - Kotlin 只获取明天的日期

javascript - 如何正确地从Kotlin.js开始

apache - 所有对 Restful web 服务的后请求都提供 Http 415