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

smdnsysy  于 4个月前  发布在  Kotlin
关注(0)|答案(1)|浏览(64)

我正在尝试构建一个应用程序,用户可以看到地球仪周围不同植物的列表。为此,我试图使用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 $
下面是我在整个过程中使用的类:SpeciesListPlant.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]这样的数组中。我如何才能在这个“data”字段中获得数组,这会解决这个错误吗?
长话短说,当我得到响应时,我如何获得与父“data”字段配对的数组。

ldioqlga

ldioqlga1#

最简单的解决方案是添加一个新的封闭数据类,它具有data属性:

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

字符串
然后将getSpeciesList()函数的返回类型改为使用该数据类:

fun getSpeciesList(): Call<SpeciesListResponse>

相关问题