预期 BEGIN_OBJECT 但在路径 $ 处 BEGIN_ARRAY - Retrofit2 与 RxJava 处理 JSONArray 响应

Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $ - Retrofit2 with RxJava handling JSONArray response

我能够让它与 JSON 对象响应一起工作,但是当我尝试 JSON 数组响应时我遇到了错误

Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $

假设我正在使用这个 JSON 数组

[
  {
    "id": 272846,
    "date": "2021-04-04T15:26:48",
    "link": "https://sample.com/crypto-that-surged-by-1250-in-2021-teams-up-with-cardano/",
    "title": {
      "rendered": "sample"
    },
    "content": {
      "rendered": "sample",
      "protected": false
    },
    "author": 52,
    "jetpack_featured_media_url": "https://sample.com/wp-content/uploads/2021/01/Untitled-design-3-1.jpg"
  },
  {
    "id": 272841,
    "date": "2021-04-04T11:03:54",
    "link": "https://sample.com/global-financial-services-company-btig-is-bullish-on-bitcoin-and-microstrategy/",
    "title": {
      "rendered": "sample"
    },
    "content": {
      "rendered": "sample",
      "protected": false
    },
    "author": 52,
    "jetpack_featured_media_url": "https://sample.com/wp-content/uploads/2021/04/3-feb-2021-05-1024x576-1.jpg"
  }
]

生成的 Kotlin (Codegen) class 使用此 plugin

class NewsItemModels : ArrayList<NewsItemModel>()
@JsonClass(generateAdapter = true)
data class NewsItemModel(
    @Json(name = "author")
    val author: Int,
    @Json(name = "content")
    val content: Content,
    @Json(name = "date")
    val date: String,
    @Json(name = "id")
    val id: Int,
    @Json(name = "jetpack_featured_media_url")
    val jetpackFeaturedMediaUrl: String,
    @Json(name = "link")
    val link: String,
    @Json(name = "title")
    val title: Title
)

有了这样的服务

 @GET("posts")
    fun getNewsItems(
        @Query("_fields") key: String,
        @Query("per_page") part: String,
        @Query("categories") category: String
    ):
            Observable<NewsItemModels>

服务接口

companion object {

        fun create(baseUrl: String): EndpointServices {

            val retrofit = Retrofit.Builder()
                .addCallAdapterFactory(
                    RxJava2CallAdapterFactory.create()
                )
                .addConverterFactory(
                    MoshiConverterFactory.create()
                )
                .baseUrl(baseUrl)
                .build()

            return retrofit.create(EndpointServices::class.java)

        }

    }

正在获取

fetch.getNewsItems(
            "author,id,title,content,date,link,jetpack_featured_media_url",
            "30",
            categoryId
        ) //Get the first channel id
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                { result ->
                    Log.wtf("WTF", "$result")
                    swipeRefreshLayout.isRefreshing = false
                },
                { error ->
                    Log.wtf("WTF", "${error.message}")
                    swipeRefreshLayout.isRefreshing = false
                }
            )

我能够尽可能地使用 JSON 对象响应,但不能使用 JSONArray 我只需要一个 Retrofit.Builder 代码。这里缺少什么?

您可以:

    @GET("posts")
    fun getNewsItems(
        @Query("_fields") key: String,
        @Query("per_page") part: String,
        @Query("categories") category: String
    ): Observable<List<NewsItemModel>>

或将您对 NewsItemModels 的定义更新为:

typealias NewsItemModels = List<NewsItemModel>

错误信息:

Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $

来自 Gson,它告诉你,根据你定义 getNewsItems 的方式,它期待一个对象(你将 NewsItemModels 定义为 class),但它得到了一个数组。

在您的示例中 JSON 接收到的有效载荷是一个数组,因此您需要更新 return 类型以内联 List 或使用 typealias