【问题标题】:RETROFIT Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ KOTLINRETROFIT 应为 BEGIN_ARRAY,但在第 1 行第 2 列路径 $ KOTLIN 处为 BEGIN_OBJECT
【发布时间】:2021-08-05 05:19:57
【问题描述】:

大家好,我正在尝试从 API 获取数据。我可以使用这个https://raw.githubusercontent.com/atilsamancioglu/K21-JSONDataSet/master/crypto.json json 文件,但我不能让它工作。 https://www.episodate.com/api/most-popular?page=1

这是我的主要活动

private fun loadData(){

    val retrofit = Retrofit.Builder()
            .baseUrl("https://www.episodate.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(MovieAPI::class.java)

    CoroutineScope(Dispatchers.IO).launch {
        val response = retrofit.getData()

        if (response.isSuccessful){
            response.body()?.let {
                Moviemodel = ArrayList(it)
            }
        }
        println(Moviemodel)

    }

我的数据类

data class MovieModel(
    val name: String
)

和 API 类

interface MovieAPI {
@GET("api/most-popular?page=1")
suspend fun getData(): Response<ArrayList<MovieModel>>

当我尝试https://raw.githubusercontent.com/atilsamancioglu/K21-JSONDataSet/master/crypto.json 这个文件时,我可以获得数据,但每当我尝试这个https://www.episodate.com/api/most-popular?page=1 时,应用程序就会崩溃。请看一下谢谢。

【问题讨论】:

  • 不能为不同的响应体使用同一个模型类,为第二个API生成另一个模型类。
  • 我做到了。我也尝试了来自 json 插件的 kotlin 数据类文件,并且我还尝试了这个数据类工作的另一个 json 文件。但是一些 json 文件会导致崩溃。没找到

标签: java android kotlin retrofit kotlin-coroutines


【解决方案1】:

How to parse nested List with Retrofit and Gson? 这是一个类似的问题。你的模型应该是这样的

data class Movie(
    val page: Int,
    val pages: Int,
    val total: String,
    val tv_shows: List<TvShow>
)
data class TvShow(
    val country: String,
    val end_date: Any,
    val id: Int,
    val image_thumbnail_path: String,
    val name: String,
    val network: String,
    val permalink: String,
    val start_date: String,
    val status: String
)

然后是API类

interface MovieAPI {
@GET("api/most-popular?page=1")
suspend fun getData(): Response<Movie>//instead of Response<ArrayList<Movie>>

在活动中

 CoroutineScope(Dispatchers.IO).launch {
        val response = retrofit.getData()

        if (response.isSuccessful){
            response.body()?.let {
                shows = List(it.tv_shows)
            }
        }
       for(show in shows){
       println(show.name) // here are the names
       }
    }

如果您想为模型使用不同的属性名称,您应该使用 @SerializedName() 注释这些属性名称。更多信息请参考Gson: @Expose vs @SerializedName

【讨论】:

  • 它有效,但我可以问一个问题吗?为什么我们使用 Response 而不是 Response>
  • @Tunahan 正如 Sushant Hande 所提到的,因为您的 API 响应以花括号“{}”开头,它是一个 JSON 对象,而不是 JSON 数组。所以它不是一个列表,它是一个单一的对象。请再次查看他的答案并查看here
【解决方案2】:

第一个是 json 列表,但第二个是包含列表的 json 对象,因此您无法直接解析为列表。您应该有包含列表对象的类。 例如:

data class MoviePageModel(
    val total: Int,
    val page: Int,
    val tvShows: List<MovieModel>
)

【讨论】:

  • 我做到了下一步我应该怎么做我正在尝试但仍然崩溃。
【解决方案3】:
  1. https://raw.githubusercontent.com/atilsamancioglu/K21-JSONDataSet/master/crypto.json
    如果来自此 URL 的响应,如果您看到响应用方括号括起来,即“[]”。这意味着响应将在 JSON 数组中。

  2. https://www.episodate.com/api/most-popular?page=1
    如果来自此 URL 的响应,如果您看到响应用大括号括起来,即“{}”。这意味着响应将在 JSON 对象中。

在下一行中,您提到响应将是 MovieModel 的 ArrayList,但实际上在第一个 URL 的情况下它将是一个 JSON 数组,而在第二个 URL 的情况下它将是一个 JSON 对象。 暂停有趣的getData():响应

为了解决这个问题,您需要为每个 URL 定义单独的响应模型。

【讨论】:

  • 我可以解决 JSON 数组,但我无法处理我无法理解我需要什么的 JSON 对象。我正在创建一个包含 tvShows: List 对象的类,但我不知道下一步需要什么。
猜你喜欢
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
相关资源
最近更新 更多