Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializer for xml data while calling http post method (Ktor lib)

As I am newbie in Android, I am building an application in which I need to update layer data on Geo server. For that scenario, I m calling post method along with XML body request.

I need to send data in xml format in request body and need to get response in xml. For that, I tried using XmlSerializer instead of JsonFeature but I got error saying "XmlSerializer is not comapanion object, need to initialize here"

val httpClient = HttpClient {
        install(JsonFeature) {
            serializer = KotlinxSerializer(Json.nonstrict)
                }
             }

Thanks in Advance!!

like image 396
RUBY KUMARI Avatar asked Aug 05 '19 07:08

RUBY KUMARI


1 Answers

There are no XML related features, but you can use existing Json with the XML serializer

The first thing you need to do is to find an appropriate serializer. I used https://github.com/pdvrieze/xmlutil.

implementation("net.devrieze:xmlutil-android:0.20.0.1")

You also can use other platform dependencies(I used the JVM and multiplatform).

Next you can configure the JsonFeature feature with a custom serializer:

val client = HttpClient {
    Json {
        serializer = XMLSerializer()
        accept(ContentType.Application.Xml)
    }
}

Using ContentType.Application.Xml

And finally, add the serializer:

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

    override fun read(type: TypeInfo, body: Input): Any {
        val text = body.readText()
        val deserializationStrategy = format.context.getContextual(type.type)

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

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

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

Here is the full result sample with the server(adopted to run without Android): https://gist.github.com/e5l/3b4d5d704b4d7c6e2a65cf68de8e9ca4

like image 118
Leonid Avatar answered Nov 04 '22 08:11

Leonid