使用 Retrofit 和 Gson 获取 Api 返回数组数组而不是对象数组

问题描述 投票:0回答:1

最近我一直在从事一个项目,其中包括使用 API。 我已经在 Postman 中检查过它,我确信它的响应是一个对象数组,但是当尝试使用它时,我遇到了 Expected BEGIN_OBJECT 但出现了 BEGIN_ARRAY 错误,所以我将 API 响应类型更改为 List 以查看会发生什么,我意识到而不是它返回对象数组,其中所有对象均为空且没有有效响应。

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 并为其提供用户名和密码,因为它是私有的并且需要 授权:

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

data class Product(

     /// its attributes are here

    )
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)]

[{
    "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": "",
   
and it continues like this and is more than 600 lines
android kotlin gson retrofit
1个回答
0
投票

ApiService
方法的返回类型应该直接是所需的响应类型(或者可以将其包装在
retrofit2.Response
内,例如
Response<MyClass>
)。不需要单独的
ProductResponse
类,它只保存实际的响应数据。

因此,由于您的 API 返回 JSON 数组,因此您的服务方法应该将

List<...>
作为返回类型(或 Gson 可以从 JSON 数组反序列化的任何其他类型)。

您获得大量

ProductResponse(products=null)
的原因是您已指定
List<ProductResponse>
作为返回类型。所以 Gson 期望以下 JSON 结构:

[
  {
    "products": [
      { ... },
      ...
    ]
  },
  {
    "products": [
      { ... },
      ...
    ]
  },
  ...
]

(并且因为 Gson 忽略了缺失的字段,所以

ProductResponse#products
简单地保留了
null

要解决此问题,请更改

getAllProducts
的返回类型并删除
ProductResponse
类:

@GET("products")
suspend fun getAllProducts(): List<Product>
© www.soinside.com 2019 - 2024. All rights reserved.