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添加自定义适配器处理数组转对象的逻辑:
- 编写自定义适配器类:
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) { // 不需要序列化场景可空实现,有需求时自行补充逻辑 } }
- 在构建Moshi实例时注册适配器:
val moshi = Moshi.Builder() .add(CodesAdapter()) .build()
- 简化
Codes类定义:
data class Codes( val currencyCode: String )
补充提示
- Kotlin数据类属性优先使用
val而非var,仅在需要修改属性值时使用var - 属性命名建议遵循Kotlin驼峰命名规范,通过
@Json注解映射JSON中的下划线命名字段
内容的提问来源于stack exchange,提问作者Ahmadddd4
相关产品推荐
相关产品推荐

