英文:
expected BEGIN_OBJECT but was BEGIN_ARRAY in Retrofit2
问题
我正在尝试使用Retrofit发布这个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)
但是我不能用Retrofit做同样的事情。这是我的服务接口:
@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
英文:
I am trying to post this json object with retrofit
{
"ingredients": [
{
"quantity": 1,
"measureURI": measureUri,
"foodId": foodId
}
]
}
I succeeded using 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)
But I can not do same with retrofit.
Here is my service interface
@POST(Constants.API_PATH_NUTRIENTS + "?app_id=" + Constants.APP_ID + "&app_key=" + Constants.API_KEY)
Call<NutrientsResponseSchema> getFoodNutrients(@Body NutrientsRequestSchema requestSchema);
And Request schema models
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;
}
}
When I run code and request from service I get
>
> com.google.gson.JsonSyntaxException:
> java.lang.IllegalStateException: Expected BEGIN_OBJECT but was
> BEGIN_ARRAY at line 298 column 20 path $.ingredients
>
答案1
得分: 1
错误消息很明确,您已经定义了 NutrientsResponseSchema
,以使您期望食材是一个对象,但服务器返回的食材明显是一个数组,正如以下所示:
{
"ingredients": [
{
"quantity": 1,
"measureURI": measureUri,
"foodId": foodId
}
]
}
ingredients
是一个 Ingredient
数组。但在您的 NutrientsResponseSchema
中,您必须已经定义了如下内容:
@SerializedName("ingredients")
public Ingredient ingredient; //POJO and not a list of POJO
您可以通过将 NutrientsResponseSchema
更改为以下内容轻松解决此问题:
@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;
}
英文:
The error message is clear, you have defined NutrientsResponseSchema
such that, you expected ingredients to be an object but the ingredients from server is definitely an array as suggested by
{
"ingredients": [
{
"quantity": 1,
"measureURI": measureUri,
"foodId": foodId
}
]
}
ingredients
is an array of Ingredient
. but in your NutrientsResponseSchema
, you must have defined
@SerializedName("ingredients")
public Ingredient ingredient; //POJO and not a list of POJO
You can easily fix this by, changing your NutrientsResponseSchema
as
@SerializedName("ingredients")
public List<Ingredient> ingredients; //List of POJO
EDIT: To explain more:
You have your 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;
}
You need to change your last line to:
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;
}
and Ingredient
can be:
public class Ingredient{
public float quantity;
public String food;
public String foodId;
public float weight;
public float retainedWeight;
public String measureUri;
public String status;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论