Reputation: 137
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)
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"
}
]
}
maybe it will help someone in the future
response.errorBody()!!.charStream().toString()
instead should be
response.errorBody()?.source()
Upvotes: 4
Views: 6591
Reputation: 8442
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.
Upvotes: 2