android - 无法使用 Retrofit 2.6.1 成功发送 POST 请求 - JSON 转换器的问题

标签 android kotlin retrofit2 kotlin-coroutines moshi

我正在使用带有挂起协程的新 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 来生成正确的适配器(因此数据类中的注释),但无济于事。该类已生成,但未使用。我尝试像这样使用 JsonAdapterFactory 传递 Moshi var moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()到我的 ConverterFactory 但这也不起作用。 尝试将生成的适配器手动添加到 moshi,但这也不起作用。

我还尝试在我的请求中返回不同类型。 Retrofit 文档指出,如果没有转换器,则只能返回 ResponseBody ,但结果相同:Retrofit 提示它没有转换器。返回Call<Void>也是如此

我感觉我好像错过了什么?谁可以帮忙?很高兴提供更多详细信息,请索取所需内容。

最佳答案

您的请求函数应如下所示。

@Headers( "Content-Type: application/json" )
@POST("/tokens?type=56427890283537921")
suspend fun sendFirebaseToken(@Body tokenRequest: RequestBody): TokenResponse

您不使用Call<...>因为您已将其标记为暂停。

关于android - 无法使用 Retrofit 2.6.1 成功发送 POST 请求 - JSON 转换器的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58038917/

相关文章:

android - 更改 Android-Seekbar 的大小?

java - 包含 ListView 的动态导航选项卡数量

java - 在 Android Room 数据库中存储 List<Object>

multithreading - Kotlin 实现多线程请求对冲?

android - 如何在 Android 中实现 webhook?

java - 如何使用注解通过改造 2 在 android 中解析动态 json

android - 在 Android ADT r21.1 新 Activity 向导中禁用 "Finish"按钮

android - 使用 HTML5 在 android webview 上播放视频时出现问题?

java - Android:在没有图形更改的情况下禁用复选框?

android - 检测到 NFC 标签时显示 toast 消息