I have data class defined, configured gson and created rout to handle post request as follows:
data class PurchaseOrder(val buyer: String, val seller: String,
val poNumber: String, val date: String,
val vendorReference: String)
install(ContentNegotiation) {
gson {
setDateFormat(DateFormat.LONG)
setPrettyPrinting()
}
post("/purchaseOrder"){
val po = call.receive<PurchaseOrder>()
println("purchase order: ${po.toString()}")
call.respondText("post received", contentType =
ContentType.Text.Plain)
the following JSON is sent in POST request
{
"PurchaseOrder" : {
"buyer": "buyer a",
"seller": "seller A",
"poNumber": "PO1234",
"date": "27-Jun-2018",
"vendorReference": "Ref1234"
}
}
The output shows all nulls.
purchase order: PurchaseOrder(buyer=null, seller=null, poNumber=null,
date=null, vendorReference=null)
Reading data from call.request.receiveChannel() does show correct JSON. So I am receiving the data but call.receive() does not seem to produce expected results.
Got JSON manually and tried to create PurchaseOrder as follows bu no luck:
val channel = call.request.receiveChannel()
val ba = ByteArray(channel.availableForRead)
channel.readFully(ba)
val s = ba.toString(Charset.defaultCharset())
println(s) // prints JSON
val gson = Gson()
val po = gson.fromJson(s, PurchaseOrder::class.java)
println("buyer = ${po.buyer}" //prints null
To get JSON from a REST API endpoint, you must send an HTTP GET request and pass the "Accept: application/json" request header to the server, which will tell the server that the client expects JSON in response.
Create a new Ktor project Name: Specify a project name. Location: Specify a directory for your project. Build System: Make sure that Gradle Kotlin is selected as a build system. Website: Leave the default example.com value as a domain used to generate a package name.
The problem is that you have wrapped your json in "PurchaseOrder"
.
If you post this instead:
{
"buyer": "buyer a",
"seller": "seller A",
"poNumber": "PO1234",
"date": "27-Jun-2018",
"vendorReference": "Ref1234"
}
it correctly receives the following:
purchase order: PurchaseOrder(buyer=buyer a, seller=seller A, poNumber=PO1234, date=27-Jun-2018, vendorReference=Ref1234)
If you want to keep the json request as is, you have 2 options.
A custom gson serializer that expects the request to be wrapped in PurchaseOrder
.
A wrapper class like this:
class PurchaseOrderWrapper(
val purchaseOrder: PurchaseOrder
)
Then you can receive like this:
call.receive<PurchaseOrderWrapper>().purchaseOrder
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With