如何在 Retrofit 中将数据类与 API 的 JSON 响应相匹配?

How to match data class with JSON response from API in Retrofit?

提问人:AboKaid 999 提问时间:7/21/2023 最后编辑:Brian Tompsett - 汤莱恩AboKaid 999 更新时间:7/22/2023 访问量:56

问:

data class Item(
    val calories: Int,
    val carbohydrates_total_g: Double,
    val cholesterol_mg: Int,
    val fat_saturated_g: Int,
    val fat_total_g: Double,
    val fiber_g: Double,
    val name: String,
    val potassium_mg: Int,
    val protein_g: Double,
    val serving_size_g: Int,
    val sodium_mg: Int,
    val sugar_g: Double
)

data class nutritionData(
    val items: List<Item>
)

val client = OkHttpClient.Builder()
.addInterceptor { chain ->
    val request = chain.request()
        .newBuilder()
        .addHeader("X-Api-Key", ApiHeaders.API_KEY)
        .build()
    chain.proceed(request)
}
.build()

interface NinjaAPI {

    @GET("v1/nutrition?")
    fun getNutrition(@Query("query") foodName: String): Call<List<nutritionData>>
}

    const val BASE_URL = "https://api.calorieninjas.com/"
fun getMyNutrition(foodName: String) {

    val retrofitBuilder = Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl(BASE_URL)
        .client(client)
        .build()
        .create(NinjaAPI::class.java)

    val retrofitData = retrofitBuilder.getNutrition(foodName)
    retrofitData.enqueue(object : Callback<List<nutritionData>?> {
        override fun onResponse(
            call: Call<List<nutritionData>?>,
            response: Response<List<nutritionData>?>
        ) {
            Log.d(TAG, "IT WORKED")
        }

        override fun onFailure(call: Call<List<nutritionData>?>, t: Throwable) {
            Log.d(TAG, "onFailure: " + t.message)
        }
    })
}

我尝试了所有方法来显示来自 CaloriesNinja API 的(卡路里、脂肪、蛋白质和碳水化合物),但我不能,我试图检查 catlog 以获取信息,结果发现 e 从未发生过,所有按钮单击都进入并产生:onResponsonFailure

onFailure:预期BEGIN_ARRAY但在第 1 行第 2 列路径 $ 上BEGIN_OBJECT

我用谷歌搜索了一下,这是我对 API 数据的正确格式,但我复制了他们的响应示例并使用插件将其转换为 kotlin 类。

JSON的 科特林 gson的 改造

评论


答:

0赞 Marcono1234 7/22/2023 #1

您指定为 API 调用的返回类型,这意味着 JSON 数据必须如下所示:Call<List<nutritionData>>

[
  {
    "items": [ ... ]
  },
  {
    "items": [ ... ]
  },
  ...
]

但是,JSON 数据实际上只是一个 JSON 对象,它直接表示您的:nutritionData

{
  "items": [ ... ]
}

因此,您应该更改为 .Call<List<nutritionData>>Call<nutritionData>

这也是 Gson 异常消息所说的:您指定的类型是 Gson 需要 JSON 数组,但 JSON 数据实际上以 JSON 对象开头。异常的位置信息“行 1 列 2 路径 $”将您指向 JSON 数据中的该错误位置(可能有一些轻微的不准确之处)。List<...>