首页 > 解决方案 > 预期 BEGIN_OBJECT 但在 Retrofit2 中是 BEGIN_ARRAY

问题描述

我正在尝试通过改造发布这个 json 对象

{
  "ingredients": [
    {
      "quantity": 1,
      "measureURI": measureUri,
      "foodId": foodId
    }
  ]
}

我成功使用了python:

import requests

APP_ID = "app_id_"
API_KEY = "api_key"
BASE = "https://api.edamam.com/api/food-database/v2/nutrients?"

url = f"https://api.edamam.com/api/food-database/v2/nutrients?app_id={APP_ID}&app_key={API_KEY}"
data = {
        "ingredients": [
            {
                "quantity": 1,
                "measureURI":  "http://www.edamam.com/ontologies/edamam.owl#Measure_unit",
                "foodId":  "food_a1gb9ubb72c7snbuxr3weagwv0dd"
            }
        ]
    }

res = requests.post(url, json=data)
print(res.text) 

但我不能对改造做同样的事情。这是我的服务接口

@POST(Constants.API_PATH_NUTRIENTS + "?app_id=" + Constants.APP_ID + "&app_key=" + Constants.API_KEY)
Call<NutrientsResponseSchema> getFoodNutrients(@Body NutrientsRequestSchema requestSchema);

和请求模式模型

public class NutrientsRequestSchema {
    public List<IngredientsRequestSchema> ingredients;

    public NutrientsRequestSchema(List<IngredientsRequestSchema> ingredients) {
        this.ingredients = ingredients;
    }
}
public class IngredientsRequestSchema {
    public float quantity;
    public String foodId;

    @SerializedName("measureURI")
    public String measureUri;

    public IngredientsRequestSchema(float quantity,
                                    String measureUri,
                                    String foodId) {
        this.quantity = quantity;
        this.measureUri = measureUri;
        this.foodId = foodId;
    }
}

当我从服务运行代码和请求时,我得到

com.google.gson.JsonSyntaxException:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was
BEGIN_ARRAY at line 298 column 20 path $.ingredients 

标签: javaandroidjsongsonretrofit2

解决方案


错误消息很清楚,您已经定义NutrientsResponseSchema了,您期望成分是一个对象,但来自服务器的成分绝对是一个数组,如建议的那样

{
  "ingredients": [
    {
      "quantity": 1,
      "measureURI": measureUri,
      "foodId": foodId
    }
  ]
}

ingredients是一个数组Ingredient。但在你的NutrientsResponseSchema,你必须定义

   @SerializedName("ingredients")
    public Ingredient ingredient; //POJO and not a list of POJO

您可以通过更改您的NutrientsResponseSchemaas轻松解决此问题

   @SerializedName("ingredients")
    public List<Ingredient> ingredients; //List of POJO

编辑:解释更多:

你有你的NutrientsResponseSchema

public class NutrientsResponseSchema {
    public String uri;
    public float calories;
    public float totalWeight;
    public List<String> dietLabels;
    public List<String> healthLabels;
    public List<String> cautions;
 
    public TotalNutrients totalNutrients;
    public Ingredients ingredients;
}

您需要将最后一行更改为:

public class NutrientsResponseSchema {
    public String uri;
    public float calories;
    public float totalWeight;
    public List<String> dietLabels;
    public List<String> healthLabels;
    public List<String> cautions;
 
    public TotalNutrients totalNutrients;
    @SerializedName("ingredients")
    public List<Ingredient> ingredients;
}

并且Ingredient可以是:

public class Ingredient{
    public float quantity;
    public String food;
    public String foodId;
    public float weight;
    public float retainedWeight;
    public String measureUri;
    public String status;
}

推荐阅读