I want to parse the following JSON API response into the list of objects. As you can see, the field "record" is polymorphic.
[
{
"t_id": "638975A6-3E5A-4D38-82A0-1CEF7A006AC6",
"table": "ticket",
"record": {
"ticket_id": "111",
"fk_project": "29446",
"fk_phase": "64379",
"fk_status": "159406",
// many more different fields
"created": "2023-06-19 15:00:26"
}
},
{
"t_id": "912975A6-AB5A-5D40-12B2-1CEF7AAAAC23",
"table": "comment",
"record": {
"comment_id": "25666",
"role_id": "71758",
"resource": "list",
// many more different fields
"created": "2023-10-03 22:28:21"
}
}
]
My code that uses moshi looks like this:
@GET("api")
suspend fun api(): Response<List<MyResponse>>
@JsonClass(generateAdapter = true)
data class MyResponse(
val t_id: String,
val table: String,
val record: Map<String, String?>
)
But I get com.squareup.moshi.JsonEncodingException: Use JsonReader.setLenient(true) to accept malformed JSON at path $
with my implementation.
I have seen this question, but in my case there aren't just 2 types, but 100+ (ticket, comment, isssue ... 100 more). I also cannot use the Polymorphic Adapter because of the same reason. How can I parse this polymorphic field as Map<String, String?>
?
Turns out there was no problem in parsing the polymorphic field as Map<String, String?>
.
The root cause was okhttp. I was manually setting the Content-Encoding to gzip, which disabled the okhttp decompression, so my json response was a compressed gibberish.
Apparently, setting this header is something that you shouldn't do unless you want your own custom decompression. Okhttp adds this header and decompresses behind the scenes. See this.