Solution 1 :
If you want to use Moshi with Kotlin reflection you have to don’t forget to add KotlinJsonAdapterFactory
. This will work fine I guess:
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
val jsonAdapter = moshi.adapter(BaseValidation::class.java)
val baseValidation = jsonAdapter.fromJson(response.errorBody()!!.charStream().toString())!!
also, you can remove @JsonClass
annotation from your classes. It’s not needed for while you are using reflection.
Problem :
Retrofit Instance:
fun getMoshi() : Moshi{
return Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
}
fun retrofit(baseUrl: String): Retrofit = Retrofit.Builder()
.client(getClient())
.baseUrl(baseUrl)
.addConverterFactory(MoshiConverterFactory.create(getMoshi()).asLenient())
.build()
}
BaseValidation model:
@JsonClass(generateAdapter = true)
data class BaseValidation (
val status : String,
val data : List<Data>
)
response parsing:
val type: Type = Types.newParameterizedType(String::class.java, Data::class.java)
val moshi = Moshi.Builder().build()
val jsonAdapter: JsonAdapter<Map<String,Data>> = moshi.adapter(type)
val baseValidation = jsonAdapter.fromJson(response.errorBody()!!.charStream().toString())!!
results in:
Platform class java.lang.String in java.lang.String<com.example.vow.data_remote.model.create.response.validation.Data> requires explicit JsonAdapter to be registered
I am new to Moshi and kind of confused how to parse correctly, I’ve managed to achieve the result with gson using code below, but I want to learn how it’s done with Moshi:
val gson = Gson()
val type = object : TypeToken<BaseValidation>() {}.type
var errorResponse: BaseValidation? = gson.fromJson(response.errorBody()!!.charStream(), type)
is the Type below defined correctly?
val type: Type = Types.newParameterizedType(String::class.java, Data::class.java)
UPDATE
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter: JsonAdapter<BaseValidation> = moshi.adapter(BaseValidation::class.java).lenient()
val baseValidation = jsonAdapter.fromJson(response.errorBody()!!.charStream().toString())!!
returns
com.squareup.moshi.JsonEncodingException: Use JsonReader.setLenient(true) to accept malformed JSON at path $
When moshi set to lenient() by
moshi.adapter(BaseValidation::class.java).lenient()
i get
Expected BEGIN_OBJECT but was STRING at path $
OkHttp response is
{
"status": "validation",
"data": [
{
"type": "Email",
"code": 3000,
"field": "User.contact.email",
"message": "Email is invalid"
}
]
}
SOLUTION
maybe it will help someone in the future
response.errorBody()!!.charStream().toString()
instead should be
response.errorBody()?.source()
Comments
Comment posted by chitgoks
I am actually curious if it’s possible to not create a data class that will retrieve status and data properties but instead, access the data array property right away. the status in my case is always success, so there’s no point creating a data class that will hold the status and data list. thoughts?
Comment posted by Juan José Melero Gómez
I see you’re using Retrofit with