https://kotlinlang.org logo
#ktor
Title
# ktor
h

Hamza Ahmad

10/01/2021, 6:08 AM
Hello, i'm using ktor for http requests and my response come in the below format how i can deserialize and get value from "strDefaultValue" property.
a

Aleksei Tirman [JB]

10/01/2021, 7:29 AM
You can use the pdvrieze/xmlutil library to deserialize XML body to an object and then retrieve the value of
strDefaultValue
. Here is a working solution:
Copy code
import io.ktor.client.*
import io.ktor.client.engine.apache.*
import io.ktor.client.features.json.*
import io.ktor.client.request.*
import io.ktor.content.TextContent
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.util.reflect.*
import io.ktor.utils.io.core.*
import kotlinx.serialization.*
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlElement
import nl.adaptivity.xmlutil.serialization.XmlSerialName

class XMLSerializer(private val format: XML = XML()) : JsonSerializer {

    @OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class)
    override fun read(type: TypeInfo, body: Input): Any {
        val text = body.readText()
        val deserializationStrategy = format.serializersModule.getContextual(type.type)

        val mapper = deserializationStrategy
            ?: type.kotlinType?.let { serializer(it) }
            ?: type.type.serializer()

        return format.decodeFromString(mapper, text) ?: error("Failed to parse response of type $type. The result is null.")
    }

    @OptIn(InternalSerializationApi::class)
    override fun write(data: Any, contentType: ContentType): OutgoingContent {
        val serializer = data::class.serializer() as KSerializer<Any>
        val text = format.encodeToString(serializer, data, null)
        return TextContent(text, contentType)
    }
}

suspend fun main() {
    val client = HttpClient(Apache) {
        install(JsonFeature) {
            serializer = XMLSerializer()
            accept(ContentType.Application.Xml)
        }
    }

    val response = client.get<Response>("<http://localhost:8080>") {
        contentType(ContentType.Application.Xml)
    }

    println(response.DataVersion.strDefaultValue)
}

@Serializable
@XmlSerialName("ArrayOfDataVersion", "", "")
data class Response(@XmlSerialName("DataVersion", "", "") @XmlElement(true) val DataVersion: VersionValue)

@Serializable
data class VersionValue(@XmlSerialName("strDefaultValue", "", "") @XmlElement(true) val strDefaultValue: String)
To make it work use this Gradle dependency.
58 Views