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

使用Retrofit和Gson调用API返回数组的数组而非对象数组问题

问题描述

开发一个涉及API调用的项目,通过Postman确认API响应是对象数组,但使用Retrofit结合Gson调用时,出现Expected BEGIN_OBJECT but was BEGIN_ARRAY错误。将API响应类型修改为List<ProductResponse>排查后,发现返回的是多个ProductResponse实例组成的数组,但所有实例的products字段均为null,无法获取有效数据。

相关代码

创建API服务与身份验证配置

fun createApiService(): ApiService {

    val client = OkHttpClient.Builder()
        .addInterceptor(
            BasicAuthInterceptor(
                "username",
                "password"
            )
        )
        .build()


    val api = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    return api.create(ApiService::class.java)

}

class BasicAuthInterceptor(username: String, password: String) : Interceptor {
    private var credentials: String = Credentials.basic(username, password)

    override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
        var request = chain.request()
        request = request.newBuilder().header("Authorization", credentials).build()
        return chain.proceed(request)
    }
}

该代码用于创建API服务并传入用户名密码,目标API为私有接口,需身份验证。

数据类定义

data class ProductResponse(
    val products: List<Product>
)

data class Product(
    // 产品属性定义在此
)

API接口定义

interface ApiService {

    @GET("products")
    suspend fun getAllProducts(): List<ProductResponse>

}

仓库实现类

class ProductRepositoryImpl(
    private val apiService: ApiService,
) : ProductRepository {
    override suspend fun getProducts(isInternetConnected: Boolean): List<Product> {
        val dataFromServer = apiService.getAllProducts()
        Log.v("api",dataFromServer.toString())
        return dataFromServer[0].products
    }
}

日志输出

[ProductResponse(products=null), ProductResponse(products=null), ProductResponse(products=null), ProductResponse(products=null), ProductResponse(products=null), ProductResponse(products=null), ProductResponse(products=null), ProductResponse(products=null), ProductResponse(products=null), ProductResponse(products=null)]

Postman响应示例

[{
    "name": "test",
    "type": "simple",
    "featured": false,
    "catalog_visibility": "visible",
    "description": "",
    "short_description": "",
    "price": "351000",
    "regular_price": "351000",
    "sale_price": "",
    "on_sale": false,
    "purchasable": true,
    "total_sales": 0,
    "button_text": "",
    "tax_status": "taxable",
    "tax_class": "",
    "manage_stock": false,
    "stock_quantity": null,
    "backorders": "no",
    "backorders_allowed": false,
    "backordered": false,
    "low_stock_amount": null,
    "sold_individually": false,
    "weight": "",
    "shipping_required": true,
    "shipping_taxable": true,
    "shipping_class": "",
    "shipping_class_id": 0,
    "reviews_allowed": true,
    "average_rating": "0.00",
    "rating_count": 0,
    "parent_id": 0,
    "purchase_note": "",
    // 后续内容省略,总长度超过600行
}]

解决方案

问题核心是数据类结构与API实际响应不匹配:Postman返回的是直接由Product对象组成的数组,而非包含products字段的ProductResponse数组,多余的ProductResponse导致Gson无法匹配字段,最终赋值为null。

修改步骤:

  1. 调整API接口返回类型
interface ApiService {
    @GET("products")
    suspend fun getAllProducts(): List<Product>
}
  1. 删除多余的ProductResponse数据类,并补全Product类的字段,确保与API返回属性一一对应
data class Product(
    val name: String,
    val type: String,
    val featured: Boolean,
    val catalog_visibility: String,
    val description: String,
    val short_description: String,
    val price: String,
    val regular_price: String,
    // 补充API返回的其他所有属性
)
  1. 修改仓库实现逻辑
class ProductRepositoryImpl(
    private val apiService: ApiService,
) : ProductRepository {
    override suspend fun getProducts(isInternetConnected: Boolean): List<Product> {
        val dataFromServer = apiService.getAllProducts()
        Log.v("api",dataFromServer.toString())
        return dataFromServer
    }
}

修改后Gson可正确解析API返回的对象数组,不会再出现字段为null的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:19:59