【问题标题】:JsonArray to Kotlin data class using Retrofit and GsonConverterFactory(Expected BEGIN_OBJECT but was BEGIN_ARRAY)使用 Retrofit 和 GsonConverterFactory 将 JsonArray 转换为 Kotlin 数据类(预期为 BEGIN_OBJECT 但为 BEGIN_ARRAY)
【发布时间】:2019-08-15 08:10:17
【问题描述】:

我正在尝试从 github(https://github.com/JamesFT/Database-Quotes-JSON/blob/master/quotes.json) 加载 quoteJson 文件。我是改装和所有这一切的新手,所以我只是尝试遵循并理解一个教程(https://android.jlelse.eu/android-networking-in-2019-retrofit-with-kotlins-coroutines-aefe82c4d777)。如果这很愚蠢或真的很容易,非常抱歉。我仍在为此苦苦挣扎。如果我能得到一个简短的解释,为什么它会以其他方式完成,我将不胜感激!

我查看了 Retrofit 的文档,搜索了所有类似的溢出问题。问题是,如果我尝试改变 fun getQuotes(): Deferred<Response<QuoteResponse>>fun getQuotes(): Deferred<ResponseList<Quotes>> 我收到一个错误 val quoteResponse = safeApiCall(...

    private val okHttpClient = OkHttpClient().newBuilder()
        .build()

    fun retrofit() : Retrofit = Retrofit.Builder()
        .client(okHttpClient)
        .baseUrl("https://raw.githubusercontent.com/JamesFT/Database-Quotes-JSON/master/")
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .build()


    val quoteApi : QuoteApi = retrofit().create(QuoteApi::class.java)

}

型号

   val quoteAuthor : String,
   val quoteText : String
)

// Data Model for the Response returned from the Api
data class QuoteResponse(
    val results : List<Quote>
)

//A retrofit Network Interface for the Api
interface QuoteApi{
    @GET("quotes.json")
    fun getQuotes(): Deferred<Response<QuoteResponse>>
    // fun getQuotes(): Deferred<Response<QuoteResponse>>
}
val quoteResponse = safeApiCall(
            call = {api.getQuotes().await()}, // i get the error here if i change something myself
            errorMessage = "Error Fetching Popular Movies"
        )

        return quoteResponse?.results?.toMutableList()

    }
suspend fun <T : Any> safeApiCall(call: suspend () -> Response<T>, errorMessage: String): T? {

        val result : Result<T> = safeApiResult(call,errorMessage)
        var data : T? = null

        when(result) {
            is Result.Success ->
                data = result.data
            is Result.Error -> {
                Log.d("1.DataRepository", "$errorMessage & Exception - ${result.exception}")
            }
        }


        return data

    }
    Process: com.example.quoteappmvvm, PID: 7373
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
...

Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
        at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)```

【问题讨论】:

    标签: android json kotlin gson retrofit2


    【解决方案1】:

    您面临的问题是因为响应是一个数组,但您试图将它作为一个对象来处理。

    这就是您的 QuoteApi 的样子

    interface QuoteApi{
        @GET("quotes.json")
        fun getQuotes(): Deferred<Response<List<Quote>>>
    }
    

    说明: 为了更好地为您解释它 - 您当前的预期响应是

    data class QuoteResponse(
        val results : List<Quote>
    )
    

    Retrofit 和 Gson 期望您的 JSON 响应看起来像

    {
      "results": [...here would be your Qoute objects...]
    }
    

    实际上响应只是一个数组

    [...here are Quote objects...]
    

    .

    【讨论】:

      猜你喜欢
      • 2018-02-23
      • 2019-06-14
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 2016-09-26
      • 2017-02-14
      • 2020-07-26
      • 1970-01-01
      相关资源
      最近更新 更多