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

Retrofit2请求API报BEGIN_ARRAY but was BEGIN_OBJECT错误,修改DTO后仍未解决

问题诱因

这个报错是Retrofit的Gson转换器在解析返回数据时,预期数据结构是JSON数组,但实际拿到的是JSON对象导致的:

  • 你定义的LotrRepository中getCharacters()方法返回值为List<CharacterDTO>,告诉Gson要把接口返回内容解析成一个CharacterDTO类型的数组
  • 但你给出的接口返回结构最外层是单个JSON对象(包裹了docs、total等字段),完全符合单个CharacterDTO的结构,和数组没有任何关系。你之前只补充了CharacterDTO的字段,没有修改返回值类型,Gson还是会尝试把外层对象解析为数组,所以报错没有解决。
修复方案
  1. 调整Repository接口的返回值类型
    把getCharacters()的返回值从List<CharacterDTO>改为CharacterDTO,匹配接口实际返回的外层结构:
interface LotrRepository {
    suspend fun getBooks(): List<BookDTO>
    // 修改此处返回值类型
    suspend fun getCharacters(): CharacterDTO
    suspend fun getCharacterById(characterId: String): CharacterDTO
}
  1. 修改UseCase中的数据处理逻辑
    拿到外层的CharacterDTO对象后,取出里面的docs数组,再转换为业务层需要的Character列表即可:
class GetCharactersUseCase @Inject constructor(
    private val repository: LotrRepository
) {
    operator fun invoke(): Flow<List<Character>> = flow {
        try {
            val characterDto = repository.getCharacters()
            // 取出docs列表转换为目标类型
            val characterList = characterDto.docs.map { it.toCharacter() }
            // 发射处理后的列表
            emit(characterList)
            Log.d(Tag, characterList.toString())
        } catch (e: HttpException) {
            Log.d(Tag, e.toString())
        } catch (e: IOException) {
            Log.d(Tag, e.toString())
        }
    }
}
  1. 可选校验
    建议同步检查getBooks、getCharacterById两个方法的返回值是否和对应接口的实际返回结构匹配,避免出现同类报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:15:02