Kotlin调用返回数组的API报错:Expected BEGIN_OBJECT but was BEGIN_ARRAY
问题解决:Retrofit解析数组报错
Expected BEGIN_OBJECT but was BEGIN_ARRAY 错误根源
API返回的是直接的字符串数组(["value1","value2"]),但你的代码用了一个包含values字段的对象(ApiValuesItem)去解析,Gson期望接收对象结构({}),实际收到数组结构([]),因此抛出该异常。
修正步骤
1. 删除无用的数据类
直接移除ApiValuesItem类,因为API返回的结构和该类完全不匹配,无需保留。
2. 修改ApiInterface接口
将接口返回类型改为字符串列表的Call类型:
import retrofit2.Call import retrofit2.http.GET interface ApiInterface { @GET("values") fun getApiValue(): Call<List<String>> // 用List比Array更符合Kotlin使用习惯 }
3. 修正MainActivity中的回调逻辑
响应体现在是List<String>类型,直接遍历列表拼接字符串即可:
private fun getApiValues() { val retrofitBuilder = Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl(BASE_URL) .build() .create(ApiInterface::class.java) val retrofitData = retrofitBuilder.getApiValue() retrofitData.enqueue(object : Callback<List<String>> { override fun onResponse( call: Call<List<String>>, response: Response<List<String>> ) { val responseBody = response.body() ?: return // 避免空指针崩溃 val myStringBuilder = StringBuilder() responseBody.forEach { value -> myStringBuilder.append(value) myStringBuilder.append(", ") } // 移除最后多余的逗号和空格 if (myStringBuilder.isNotEmpty()) { myStringBuilder.delete(myStringBuilder.length - 2, myStringBuilder.length) } Api_Res.text = myStringBuilder.toString() } override fun onFailure(call: Call<List<String>>, t: Throwable) { Log.d("MainActivity","onFailure: "+t.message) Api_Res.text = t.message } }) }
额外说明
- 使用
List<String>而非Array<String>是因为Kotlin中List为不可变集合,更安全且适配Retrofit+Gson的默认解析逻辑。 - 代码中添加
response.body() ?: return处理接口返回空的情况,避免!!强制非空导致的崩溃。 - 最后移除末尾多余的逗号,让显示的字符串更整洁。
内容的提问来源于stack exchange,提问作者Abbas Amhaz
相关产品推荐
相关产品推荐

