在 Kotlin 中使用 Retrofit 获取父 JSON 对象中的数组

问题描述 投票:0回答:1

我正在尝试构建一个应用程序,用户可以在其中查看全球不同植物的列表。为此,我尝试使用 Retrofit2 和 GSon 从 Perenual Plant Doc API 获取响应。这就是我的回复:

{
  "data": [
    {
      "id": 1,
      "common_name": "European Silver Fir",
      "scientific_name": [
        "Abies alba"
      ],
      "other_name": [
        "Common Silver Fir"
      ],
      "cycle": "Perennial",
      "watering": "Frequent",
      "sunlight": [
        "full sun"
      ],
      "default_image": {
        "license": 45,
        "license_name": "Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)",
        "license_url": "https://creativecommons.org/licenses/by-sa/3.0/deed.en",
        "original_url": "https://perenual.com/storage/species_image/1_abies_alba/og/1536px-Abies_alba_SkalitC3A9.jpg",
        "regular_url": "https://perenual.com/storage/species_image/1_abies_alba/regular/1536px-Abies_alba_SkalitC3A9.jpg",
        "medium_url": "https://perenual.com/storage/species_image/1_abies_alba/medium/1536px-Abies_alba_SkalitC3A9.jpg",
        "small_url": "https://perenual.com/storage/species_image/1_abies_alba/small/1536px-Abies_alba_SkalitC3A9.jpg",
        "thumbnail": "https://perenual.com/storage/species_image/1_abies_alba/thumbnail/1536px-Abies_alba_SkalitC3A9.jpg"
      }
    },
    {
      "id": 2,
      "common_name": "Pyramidalis Silver Fir",
      "scientific_name": [
        "Abies alba 'Pyramidalis'"
      ],
      "other_name": [],
      "cycle": "Perennial",
      "watering": "Average",
      "sunlight": [
        "full sun"
      ],
      "default_image": {
        "license": 5,
        "license_name": "Attribution-ShareAlike License",
        "license_url": "https://creativecommons.org/licenses/by-sa/2.0/",
        "original_url": "https://perenual.com/storage/species_image/2_abies_alba_pyramidalis/og/49255769768_df55596553_b.jpg",
        "regular_url": "https://perenual.com/storage/species_image/2_abies_alba_pyramidalis/regular/49255769768_df55596553_b.jpg",
        "medium_url": "https://perenual.com/storage/species_image/2_abies_alba_pyramidalis/medium/49255769768_df55596553_b.jpg",
        "small_url": "https://perenual.com/storage/species_image/2_abies_alba_pyramidalis/small/49255769768_df55596553_b.jpg",
        "thumbnail": "https://perenual.com/storage/species_image/2_abies_alba_pyramidalis/thumbnail/49255769768_df55596553_b.jpg"
      }
    }
  ],
  "to": 30,
  "per_page": 30,
  "current_page": 1,
  "from": 1,
  "last_page": 337,
  "total": 10102
}

根据此回复,返回了两种植物。当尝试获取数据时,就好像响应只是一个数组一样,我收到此错误:

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

以下是我在整个考验中使用的课程: 物种列表植物.kt

data class SpeciesListPlant(
    @SerializedName("common_name")
    val commonName: String,
    @SerializedName("cycle")
    val cycle: String,
    @SerializedName("default_image")
    val defaultImage: DefaultImage,
    @SerializedName("id")
    val id: Int,
    @SerializedName("other_name")
    val otherName: List<String>,
    @SerializedName("scientific_name")
    val scientificName: List<String>,
    @SerializedName("sunlight")
    val sunlight: List<String>,
    @SerializedName("watering")
    val watering: String
)

物种列表接口.kt

interface SpeciesListInterface {
    @GET(ApiConstants.SPECIES_LIST_ENDPOINT_PERENUAL)
    fun getSpeciesList(): Call<List<SpeciesListPlant>>
}

这就是我通过改造获取数据的方式

val retrofitBuilder = Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(ApiConstants.BASE_URL_PERENUAL)
                .build()
                .create(SpeciesListInterface::class.java)

            val retrofitData = retrofitBuilder.getSpeciesList()

            retrofitData.enqueue(object : Callback<List<SpeciesListPlant>?> {
                override fun onResponse(call: Call<List<SpeciesListPlant>?>, response: Response<List<SpeciesListPlant>?>) {
                    val responseBody = response.body()!!
                    Log.e("Retrofit data", responseBody.toString())
                }

                override fun onFailure(call: Call<List<SpeciesListPlant>?>, t: Throwable) {
                    t.printStackTrace()
                }
            })

我假设我收到此错误是因为我想要的数据嵌套在另一个名为“data”的对象中,而不仅仅是嵌套在像 [plant1, plant2] 这样的数组中。 我怎样才能获取这个“数据”字段中的数组,这会解决这个错误吗?

长话短说,当我收到响应时,如何将数组与父“数据”字段配对。

android kotlin gson retrofit2
1个回答
0
投票

最简单的解决方案是添加一个新的封闭数据类,它具有以下

data
属性:

data class SpeciesListResponse(
    @SerializedName("data")
    val data: List<SpeciesListPlant>
)

然后更改

getSpeciesList()
函数的返回类型以使用该数据类:

fun getSpeciesList(): Call<SpeciesListResponse>
© www.soinside.com 2019 - 2024. All rights reserved.