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

Kotlin解析汇率API返回JSON出现Expected BEGIN_OBJECT but was BEGIN_ARRAY错误求解

错误原因

你遇到的Expected BEGIN_OBJECT but was BEGIN_ARRAY报错核心原因是:JSON响应中supported_codes字段的每个子项为数组类型,但你在数据类中声明该字段为List<Codes>,Moshi默认会将Codes类映射为JSON对象,解析时预期遇到对象开头的{,实际遇到的是数组开头的[,因此抛出类型不匹配错误。

解决方案

方案1:直接使用嵌套数组类型(实现最简单)

直接将supported_codes的类型声明为嵌套字符串数组,不需要额外适配器,后续需要取值时自行映射即可,修正后的数据类代码如下:

package com.example.currencyconverter.data

import com.squareup.moshi.Json

data class CurrencyResponse(
    @Json(name = "supported_codes") 
    val supportedCodes: List<List<String>>
)

后续提取货币编码时直接取每个子数组的第0位即可:

val currencyCodeList = currencyResponse.supportedCodes.map { it[0] }

方案2:自定义JsonAdapter适配自定义类

如果你需要直接将数组映射为自定义的Codes数据类,可以为Moshi添加自定义适配器处理数组转对象的逻辑:

  1. 编写自定义适配器类:
import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonReader
import com.squareup.moshi.ToJson

class CodesAdapter {
    @FromJson
    fun fromJson(reader: JsonReader): Codes {
        reader.beginArray()
        val currencyCode = reader.nextString()
        // 第二个值为货币名称,不需要可以直接调用reader.skipValue()跳过
        val currencyName = reader.nextString()
        reader.endArray()
        return Codes(currencyCode)
    }

    @ToJson
    fun toJson(writer: com.squareup.moshi.JsonWriter, value: Codes) {
        // 不需要序列化场景可空实现,有需求时自行补充逻辑
    }
}
  1. 在构建Moshi实例时注册适配器:
val moshi = Moshi.Builder()
    .add(CodesAdapter())
    .build()
  1. 简化Codes类定义:
data class Codes(
    val currencyCode: String
)
补充提示
  • Kotlin数据类属性优先使用val而非var,仅在需要修改属性值时使用var
  • 属性命名建议遵循Kotlin驼峰命名规范,通过@Json注解映射JSON中的下划线命名字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 15:54:07