can not send int to respond in ktor - kotlin

I'm trying to send int response but get an error but when I use both as a string then response get successfully.
post("/employee") {
call.respond(mapOf("hey" to "Hey","if" to 1))
}
LOGCAT
java.lang.IllegalStateException: Serializing collections of different element types is not yet supported. Selected serializers: [kotlin.String, kotlin.Int]
at io.ktor.serialization.kotlinx.SerializerLookupKt.elementSerializer(SerializerLookup.kt:45)
at io.ktor.serialization.kotlinx.SerializerLookupKt.guessSerializer(SerializerLookup.kt:29)
at io.ktor.serialization.kotlinx.KotlinxSerializationBase.serialize$ktor_serialization_kotlinx(KotlinxSerializationBase.kt:34)
at

You can't pass different types in response "yet" like mentioned in stacktrace. As a workaround you can pass 1 as string or create custom class for this response and serialize it to json and send it like that

Related

How to send custom http response code back from spring cloud functions in gcp?

We are using the new gcp cloud functions using Java / Kotlin.
As in the current reference implementations, we are returning org.springframework.messaging.support.GenericMessage objects.
So our code looks like this (Kotlin):
fun generatePdfInBase64(message: Message<Map<String, Any>>): Message<*> {
val document = process(message)
val encoded = Base64.getEncoder().encodeToString(document.document)
return GenericMessage(encoded)
}
We were not able to find any way to include a custom http response code to our message, e.g. 201 or something. The function only responds 200 in case of no exception or 500.
Does someone know of a way to do this?
Best wishes
Andy
As it is mentioned at the official documentation, the HttpResponse class has a method called setStatusCode where you are able to set the number of the status as your convenience
For example:
switch (request.getMethod()) {
case "GET":
response.setStatusCode(HttpURLConnection.HTTP_OK);
writer.write("Hello world!");
break;
On the other hand the constructor of the GenericMessage receives as parameter a payload, therefore I think you can create a string with a json format and use the constructor for create your GenericMessage instance with the status response you need.
If you want to know more about the statuds codes take a look at this document.

Ktor returns 415 from endpoints where receive() is used with ContentNegotiation

I have parameter classes with the #Searializable annotation:
#Serializable
data class ShowPostURL(
val date: String,
val titleSlug: String,
override val redirectTo: String? = null
)
and no matter what I do call.receive() won't work. I'm getting HTTP 415 errors and Ktor doesn't log anything. I've added the serialization support as well:
install(ContentNegotiation) {
json()
}
How do I fix this? This is how I'm trying to use it:
accept(ContentType.Any) {
get("/foo/{date}/{titleSlug}") {
val input = call.receive(ShowPostURL::class)
call.respondText("foo")
}
}
If I do a trace I can see that my route is matched, but it can't receive the parameters. Is this json() setup is supposed to work when I'm deserializing from url parameters like this?
Firstly, ContentNegotiation feature works only for receiving custom objects from the payload of POST, PUT and PATCH requests:
POST, PUT and PATCH requests have an associated request body (the payload). That payload is usually encoded.
In order to receive custom objects from the payload, you have to use the ContentNegotiation feature. This is useful for example to receive and send JSON payloads in REST APIs.
When receiving, the Content-Type of the request will be used to determine which ContentConverter will be used to process that request
Secondly, there are three out of the box ContentConverter available:
GsonConverter, JacksonConverter and SerializationConverter.
Each of these converters has its own configuration function: gson, jackson and serialization respectively. You use json configuration function which is most likely is not appropriate for the configuration of ContentNegotiation.
To solve your problem you can access URL parameters by referring them with call.parameters and manually create ShowPostURL object. Then serialize it with the kotlinx.serialization framework if needed.
Also, you can write your own ContentConverter to implement custom logic for receiving typed objects.

Jackson InvalidFormatException: Cannot deserialize value of type `java.util.UUID` from String

Am using Spring boot with a Rest Controller. I have a #PostMapping with a #RequestBody having object that has id of type UUID. When I am trying to test my post request from Postman I get the following error.
JSON parse error:
Cannot deserialize value of type java.util.UUID from String "4be4bd08cfdf407484f6a04131790949": UUID has to be represented by standard 36-char representation; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.util.UUID from String "4be4bd08cfdf407484f6a04131790949": UUID has to be represented by standard 36-char representation
I read in some post that talked about invalidFormatException but with a different data type that need to write some kind of Adapter. How can I resolve this for the UUID? Thanks in advance for your input.
#PostMapping(value = "/save_order")
#ResponseStatus(HttpStatus.CREATED)
public void postOrder(#RequestBody Order order) {
...
public class Order {
#Id
private UUID dstId;
....
Never mind, I searched around and was able to resolve the issue. Below is the solution.
So basically the solution was to remove the ID from the JSON that I was using for the request body. The Json that I was using earlier had dstId as the first key, removing it resolved my error.
{
"dstId":"4be4bd08cfdf407484f6a04131790949",
...
}
Also I realized that the root cause was that the data I was using above is not a valid UUID. Using a valid UUID in it's place worked, for example
"dstId": "110841e3-e6fb-4191-8fd8-5674a5107c33
The post that helped me to figure out Spring Boot JSON parse error: Cannot deserialize error

How to get actual request object in .Net Core API when request object has become NULL?

At times, when client sends an incorrect data to a API COntroller method, the request object become NULL when received. The primary cause of request object turning NULL could be client passing NULL value to a Non-Null property etc etc.
I would like to get that actual request object which client had sent so that I can get to know what client has passed and resolve the issue.
I receive my request object as:
HttpPost]
[Route("addQuote")]
public JsonResult AddQuote([FromBody]AddQuoteRequestModel quoteRequestModel) { //Lines of code }
Here, at times the quoteRequestModel object is received as NULL. I would like to capture the exact JSON client has passed in to this method.
Is there any way I can capture that?

Unable to add body to RestSharp RestRequest using enums

I am using RestSharp in ASP .NET MVC 2 project. Trying to create RestRequest (using POST method) and add two enum values (my enum type -- OrderStatusFlags) to request body -- using build-in RestSharp XmlSerializer:
var request = new RestRequest("orders/{vendorID}/{number}", Method.POST);
request.AddBody(previousOrderStatus);
request.AddBody(newOrderStatus);
But after calling AddBody method in request parameters can see only empty but no value. And while calling MVC action method an error occurs:
The parameters dictionary contains a null entry for parameter 'previousStatus' of non-nullable type 'OrderStatusFlags' for method 'RestResponse PostOrderStatus(Int32, System.String, OrderStatusFlags, OrderStatusFlags)' in 'OrdersResourceEndpoint'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
Enum look like this:
public enum OrderStatusFlags : long
{
Pending,
Confirmed,
...
}
Does anybody occurs a similiar situation?
A couple issues here. First, you can only call AddBody() once or the last call will take precedence. AddBody() is also only for sending XML as the request body. What is the required XML schema that you need to send to that URL? Can you post some sample XML that you're trying to generate?
I think more likely you actually want to use AddParameter() to add some POST parameters since that is far more common than XML request bodies.