I'm having an issue deserializing some XMl containing a list of objects.
To reproduce it, I first serialize a given object to XML, then try to deserialize the result, but it fails.
Here is my sample code:
fun main() {
val test = CategoriesResponse(listOf(Category(1), Category(2)))
val xmlMapper = XmlMapper()
val xml: String = xmlMapper.writeValueAsString(test)
println(xml)
val testObject = xmlMapper.readValue(xml, CategoriesResponse::class.java)
println(testObject)
}
@JacksonXmlRootElement(localName = "response")
data class CategoriesResponse
@JsonCreator
constructor(
@field:JacksonXmlElementWrapper(localName = "categories")
@field:JacksonXmlProperty(localName = "category")
val categoryList: List<Category>
)
data class Category
@JsonCreator
constructor(
@field:JacksonXmlProperty(isAttribute = true)
val id: Int,
)
The produced XML is just right (formatted here):
<response>
<categories>
<category id="1"/>
<category id="2"/>
</categories>
</response>
I'm using
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml")
And here is the exception I get:
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<Category>` from Object value (token `JsonToken.FIELD_NAME`)
at [Source: (StringReader); line: 1, column: 11]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
Any help would be greatly appreciated. Thank you!
Something wrong with the constructor. I don't think @JsonCreator
is suitable for XML. Consider adding default values so the parser will instantiate the objects by triggering their empty constructors.
@JacksonXmlRootElement(localName = "response")
data class CategoriesResponse(
@field:JacksonXmlElementWrapper(localName = "categories")
@field:JacksonXmlProperty(localName = "category")
val categoryList: List<Category> = listOf()
)
data class Category(
@field:JacksonXmlProperty(isAttribute = true)
val id: Int = -1
)