Got a json list mixed with plain String and Image object like this:
{
"mixList": [
"string",
{
"imageUrl": "http://...",
"height": 320,
"width": 480
}
]
}
How to parse with Moshi?
I would expect to have a List<Data>
,
where StringData extends Data
and ImageData extends Data
I've solved this problem using Moshi
with a CustomAdaptor
. After a lot of research I wasn't able to find a better "out-of-the-box" solution. This solutions is in kotlin
but can easily be ported to Java as well.
First let's define the types we are trying to parse here. I'll call the wrapper type, that contains the mixList
, Response
:
@JsonClass(generateAdapter = true)
data class Response(val mix_types: Data)
And the 2 different types that can be inside the list StringData
and ImageData
:
sealed class Data {
data class StringData(val value: String) : Data()
@JsonClass(generateAdapter = true)
data class ImageData(
val imageUrl: String,
val height: Int,
val width: Int
) : Data()
}
As I'm using Moshi code-gen, so I have annotated Response
and ImageData
with @JsonClass(generateAdapter = true)
so that Moshi will generate the adapters for these types(and I'll leverage this in my custom adapter).
I want to provide my own custom adapter to the Data
type, and I won't also want the adapter Moshi would generate for the StringData
type, since this is precisely what I want to serialise/deserialise into a String, so I won't annotate these classes.
Now I'm gonna write my custom adapter like this:
class DataCustomAdapter {
@FromJson
fun fromJson(jsonReader: JsonReader, delegate: JsonAdapter<ImageData>): Data? {
return if (jsonReader.peek() == BEGIN_OBJECT) {
delegate.fromJson(jsonReader)
} else {
StringData(jsonReader.nextString())
}
}
@ToJson
fun toJson(jsonWriter: JsonWriter, data: Data, delegate: JsonAdapter<ImageData>) {
when (data) {
is ImageData -> delegate.toJson(jsonWriter, data)
is StringData -> jsonWriter.value(data.value)
}
}
}
all it's missing now is to register the custom adapter with Moshi:
private val moshi = Moshi.Builder()
.add(DataCustomAdapter())
.build()
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