Я использую новый Retrofit2 с приостановкой сопрограмм, и с запросами GET все работает нормально.
Но теперь мне нужно реализовать запрос POST, и я просто не могу заставить его работать
У меня есть пример CURL, который выглядит так: curl -X POST -H "Content-Type: application/json;charsets: utf-8" -d '{"tx_guapptokenlist_tokenitem":{"tokenchar":"my-token-string","platform":"android"}}' https://www.example-url.com/tokens?type=56427890283537921
Это работает нормально и возвращает этот ответ: {"errors":false,"success":true}%
Итак, вот как выглядит мой запрос прямо сейчас в моем классе Api:
@Headers( "Content-Type: application/json" )
@POST("/tokens?type=56427890283537921")
suspend fun sendFirebaseToken(@Body tokenRequest: RequestBody) : Call<TokenResponse>
Это мой класс TokenResponse:
@JsonClass(generateAdapter = true)
data class TokenResponse(
@Json(name="errors")
val errors: Boolean,
@Json(name="success")
val success: Boolean)
и класс ApiClient, который я использую:
object ApiClient {
private const val BASE_URL = "https://myExampleUrl.com"
private var retrofit: Retrofit? = null
var moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val client: Retrofit?
get() {
if (retrofit == null) {
retrofit = Retrofit.Builder().baseUrl(
BASE_URL
).client(getOkHttpClient())
.addConverterFactory(MoshiConverterFactory.create())
.build()
}
return retrofit
}
fun getOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder().addInterceptor(getLoggingInterceptor())
.connectTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS).writeTimeout(90, TimeUnit.SECONDS).build()
}
private fun getLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().setLevel(
if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.HEADERS
else HttpLoggingInterceptor.Level.NONE
)
}
}
Первое, что я заметил: даже с аннотацией @POST
, если у моего suspend fun
нет возвращаемого типа, яне получить ошибку, но okhttp всегда будет отправлять запрос GET (по крайней мере, конечная точка всегда получает GET).Не уверен, что так должно быть?
В любом случае: мне нужны возвращаемые значения, поэтому я возвращаю Call<TokenResponse>
.Это приводит меня к моей главной проблеме, которую я не могу решить: если сейчас я выполняю свой код, он вылетает с таким журналом:
java.lang.IllegalArgumentException: Unable to create converter for retrofit2.Call<myapp.communication.TokenResponse>
for method TokenApi.sendToken
at retrofit2.Utils.methodError(Utils.java:52)
Чтобы попытаться справиться с этим, я использовал moshi-kotlin-Codegen для генерации правильного адаптера (отсюда и аннотации в классе данных), но безрезультатно.Класс генерируется, но не используется.Я пытался передать Moshi с помощью JsonAdapterFactory, например, var moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
, на мой ConverterFactory, но это тоже не работает.Попытка добавить сгенерированный адаптер вручную в moshi, но это также не сработало.
Я также попытался вернуть различные типы в моем запросе.Документы Retrofit заявляют, что без конвертера можно вернуть только ResponseBody
, но результат тот же: Retrofit жалуется, что у него нет конвертера.То же самое для возврата Call<Void>
Мне кажется, что я что-то здесь упускаю?Кто может помочь?Рад предоставить более подробную информацию, пожалуйста, запросите, что нужно.