I have an API request to handle that sometimes returns with code 200 and a value of something like
{ "key" : "value" }
But in some cases, API might return with code 204. Handling this is a whole other story, but I end up with an interceptor that replaces a response body with an empty string, so it won't throw NoSuchElementException.
Now I want to handle the result with Jackson in a way, that in a case of 200 I would get an object of class A described like this:
class A(#JsonProperty("key") val value: String?)
But in the case of 204 and empty body response, I would like to get an instance of A with value property equals null.
I've tried adding a custom deserialiser, but I get the following exception even before my deserialiser code is executed:
com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input at [Source: (String)""; line: 1, column: 0]
This is kind of obvious since there's no top-level JSON object in an empty string.
Is there a way I can achieve desired behaviour using Jackson?
I'm not familiar with Jackson but I notice you said
I end up with an interceptor that replaces a response body with an empty string
Can't you just then instead of empty string return "{ \"key\" : null }" instead?
Related
I have an API which its response is kind of dynamic. I mean sometimes it return a Jason object with "token" value, and sometimes it returns with "message" value. For handling this scenario I decided to have both field in my data class like below:
data class response {
val message:String;
val token:String;
}
Now I want to make both fields optional in Kotlin serialization. I mean, I want to tell Kotlin serialization that if you couldn't find token in response JSON it's ok to ignore it.
How can I achieve this?
All Kotlin properties with default values are automatically optional.
All I need to do is this:
data class response {
val message:String="";
val token:String="";
}
iam using retrofit 2 with moshi and i have a problem when the optional nested class is broken.
Lets take this as a simple example:
class ClassA(val anyString: String, classB: ClassB?)
class ClassB(val firstString: String, val secondString: String)
I have a class A that has an optional Value from class B.
The Json that is gonna be parsed looks like this:
{
"anystring":"HelloWorld",
"classB":{
"firstString":"IamAFirstString"
//SECOND STRING IS MISSING OR IS NULL
}
}
When i try to parse this json ill get an exception:
com.squareup.moshi.JsonDataException: Non-null value 'secondString' was null at $.classB.secondString
What i want to archive is that i get the ClassA with an null value at classB because that value is optional so its okay when its null. I know that can archive this when i build an adapter and catch the exception but i want to know if theres a general way to archive this behaviour without creating an adapter for every json that i have to parse.
I am currently working on an android app where I am using moshi to parse the response from retrofit as json. But I have the problem that one or more fields in the response body are sometimes included and sometimes not, based on what data you are getting back.
For example:
sometimes you get back this (case 1):
{
"fieldAaa": 33,
"fieldBee": 2
}
and sometimes this (case 2):
{
"fieldAaa": 33
}
My data class for the request body would currently look like this
data class RequestBodyTemplate(
val fieldAaa: Int,
val fieldBee: Int
)
so there is no distinction between the 2 cases mentioned above, which results in a crash when case 2 is present (meaning fieldBee is missing in the response)
Is there a way in moshi to mark this field as optional maybe(or other solution), or is there a solution in retrofit?
I have a data class
data class Bean {
var value: String = ""
}
I got a Json from server:
{
"value":null
}
What I expect is since value is not optional, so the null cannot be assigned and value will remain as "". But using the debugger I found that value is null, and therefore some method I called on it throws the below exception:
fun matches(stringToMatch: String): Boolean {
return this.value.toLowerCase() == stringToMatch.toLowerCase()
}
kotlin.TypeCastException: null cannot be cast to non-null type java.lang.String
How can I make value remains ""?
You're using a JSON deserialization library (GSON?) that creates your objects by completely sidestepping the initialization you built into them. Most probably it uses a low-level, non-JDK call sun.misc.Unsafe.allocateObject() to allocate a raw data block for your object and then proceeds to populate it from parsed JSON.
The only way to truly fix this is using such a JSON library that understands Kotlin and can replicate its object initialization rules.
BTW your specific JSON example, which explicitly assigns null to a non-null property, should not use the default value, but throw a validation exception.
How do I make Retrofit / Robospice handle my api responses in a way that I can get an empty JSON response body like: {}, but also a regular JSON response body?
Currently the empty response body initialises a new POJO, but I only want this to happen if there is actually a filled response body.
I have an object that contains three booleans, and these will always be set to false, while this shouldn't happen.
I somehow have the idea this is caused by my GSON deserializer (I use the default one), but don't know where to start for something like this.
Thanks for any help. :)
Why not using Boolean instead of boolean? That way the default value in null rather than false
Retrofit doesn't touch fields if there's no such fields in json. So init them by yourself.
public class Response {
public boolean value = true;
}