You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Retrofit/Gson报错:Expected BEGIN_OBJECT but was BEGIN_ARRAY及JSON问题

问题根源与解决方案

Flask端修改:返回带列名的JSON

你当前用cursor.fetchall()拿到的是无列名的元组列表,所以jsonify返回的是纯数组,没有字段名,导致Android端无法映射到TestPin的属性。要返回带列名的JSON,需要把元组转成字典:

cursor.execute('SELECT * FROM TestDB')
# 获取所有列名
columns = [desc[0] for desc in cursor.description]
# 把每一行元组转换成字典(列名作为键)
Testdata = [dict(zip(columns, row)) for row in cursor.fetchall()]
print(Testdata)
cursor.close()
conn.close()
return jsonify(Testdata)

这样返回的JSON格式会变成:

[
  {"id":1, "name":"Test", "location":"010100000085EB51B81E0524400000000000B49840", "day1":"Monday", "day2":"Tuesday", "day3":"wed"},
  {"id":2, "name":"Test2", "location":"010100000085EB51B81E0524400000000000B49840", "day1":"Monday", "day2":"Tuesday", "day3":"wed"}
]

Android端调整:确保字段映射正确

改成Call<List<TestPin>>是正确的,但要保证TestPin的字段名和Flask返回的JSON键完全一致,或者用@SerializedName做映射:

比如你的数据库列名如果是id、name、location、day1、day2、day3,那TestPin应该这么写:

data class TestPin(
    val id: Int,
    val name: String,
    val location: String,
    @SerializedName("day1") val monday: String, // 如果想给字段起别名,用这个注解
    val day2: String,
    val day3: String
)

同时检查Retrofit初始化是否添加了Gson转换器:

val retrofit = Retrofit.Builder()
    .baseUrl("你的Flask API地址")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

val testAPI = retrofit.create(TestAPI::class.java)

关键误区说明

  1. Flask端:fetchall()返回的是元组集合,不是字典,必须手动关联列名才能生成带键的JSON,否则Android端无法识别字段。
  2. Android端:初始的TestResponse期望API返回一个包含Tests数组的对象,但Flask返回的是直接的数组,所以会报Expected BEGIN_OBJECT but was BEGIN_ARRAY错误,改成Call<List<TestPin>>是正确的,但要确保字段映射匹配。

内容的提问来源于stack exchange,提问作者Bizes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 08:25:30