Я пытаюсь использовать Джексона через Kotlin для десериализации xml, предоставленной API lastfm. У меня это работало в Java с JAXB, и я пытаюсь его портировать. Все работает, за исключением развернутых полей списка - отслеживание в примере ниже. Я знаю, что класс данных 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\""')
at [Source: (ByteArrayInputStream); line: 1, column: 205] (through reference chain: info.eidson.lastfm.RecentTracks["track"]->java.util.ArrayList[1])
, и я считаю, что он пытается использовать класс List в качестве POJO вместо Track.
I ' мы попытались использовать обычный класс вместо класса данных с тем же результатом. Согласно 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\""</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 & 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+&+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>