Issue
I'm having a problem with MoshiConverterFactory and Retrofit - I can't send POST JSON request to RestAPI, because it always results in an error. I could do it successfully using Multipart, but the API doesn't support it, so it's out of the question...
My singleton object that holds the reference to the service:
object Singleton {
val okhttp = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()
val moshi = Moshi.Builder().build()
val retrofit = Retrofit.Builder()
.baseUrl("https://some_shows_api.com/api/")
.client(okhttp)
.addConverterFactory(MoshiConverterFactory.create())
.build()
val service = retrofit.create(ShowsApiService::class.java)
}
Register user method that causes the problem in my ViewModel:
fun registerUser(email: String, password: String) {
val authData = AuthData(email, password)
Singleton.service.register(authData).enqueue(object : Callback<Register> {
override fun onFailure(call: Call<Register>, t: Throwable) {
// some errror implementation
}
override fun onResponse(call: Call<Register>, response: Response<Register>) {
if (response.isSuccessful) {
val body = response.body()
if (body != null) {
// login user
} else {
// some error implementation
}
}
}
})
}
My interface:
data class AuthData(
val email: String,
val password: String
)
interface ShowsApiService {
@Headers("Content-Type: application/json")
@POST("users")
fun register(@Body authData: AuthData): Call<Register>
}
What I already tried to do: adding @field:Json()
annotations on parameters of my AuthData class (error is still the same), passing data with multipart and form-url-encoded (the API doesn't support it). Does anyone see what am I doing wrong? I also don't see some online examples of people using Moshi with Retrofit... Any help or tip will be much appreciated. Thanks!
Error:
FATAL EXCEPTION: main
Process: com.frideriklab.android_course, PID: 7774
java.lang.IllegalArgumentException: Unable to create @Body converter for class com.frideriklab.android_course.AuthData (parameter #1)
for method ShowsApiService.login
at retrofit2.Utils.methodError(Utils.java:52)
at retrofit2.Utils.parameterError(Utils.java:57)
at retrofit2.RequestFactory$Builder.parseParameterAnnotation(RequestFactory.java:735)
at retrofit2.RequestFactory$Builder.parseParameter(RequestFactory.java:306)
at retrofit2.RequestFactory$Builder.build(RequestFactory.java:193)
at retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:67)
at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:26)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)
at retrofit2.Retrofit$1.invoke(Retrofit.java:149)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy0.login(Unknown Source)
at com.frideriklab.android_course.ShowsViewModel.loginUser(ShowsViewModel.kt:85)
at com.frideriklab.android_course.AuthFragment$onViewCreated$3.onClick(AuthFragment.kt:56)
at android.view.View.performClick(View.java:6669)
at android.view.View.performClickInternal(View.java:6638)
at android.view.View.access$3100(View.java:789)
at android.view.View$PerformClick.run(View.java:26145)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalArgumentException: Cannot serialize Kotlin type com.frideriklab.android_course.AuthData. Reflective serialization of Kotlin classes without using kotlin-reflect has undefined and unexpected behavior. Please use KotlinJsonAdapter from the moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact.
at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:83)
at com.squareup.moshi.Moshi.adapter(Moshi.java:138)
at com.squareup.moshi.Moshi.adapter(Moshi.java:98)
at retrofit2.converter.moshi.MoshiConverterFactory.requestBodyConverter(MoshiConverterFactory.java:106)
at retrofit2.Retrofit.nextRequestBodyConverter(Retrofit.java:282)
at retrofit2.Retrofit.requestBodyConverter(Retrofit.java:262)
at retrofit2.RequestFactory$Builder.parseParameterAnnotation(RequestFactory.java:732)
Solution
I also never used Moshi. But you can try this as alternative.
@POST("users")
fun register(@Body authData: Map<String, String>): Call<Register>
And create map as below:
fun registerUser(email: String, password: String) {
val authData = HashMap<String, String>()
authData.put("email", email)
authData.put("password", password)
Singleton.service.register(authData).
...
}
Answered By - Md. Asaduzzaman
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.