【问题标题】:Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $ - Retrofit2 with RxJava handling JSONArray response预期 BEGIN_OBJECT 但在路径 $ 处是 BEGIN_ARRAY - 使用 RxJava 处理 JSONArray 响应的 Retrofit2
【发布时间】:2021-06-30 18:18:40
【问题描述】:

我能够使其与 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"
  }
]

使用这个plugin生成的Kotlin(Codegen)类

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 代码。这里缺少什么?

【问题讨论】:

    标签: android kotlin retrofit2 rx-java moshi


    【解决方案1】:

    你可以这样做:

        @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>
    

    错误信息:

    预期为 BEGIN_OBJECT,但在路径 $ 处为 BEGIN_ARRAY

    来自 Gson,它告诉您,根据您定义 getNewsItems 的方式,它需要一个对象(您将 NewsItemModels 定义为一个类),但它正在获取一个数组。

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

    【讨论】:

    • 我试过 Observable&lt;List&lt;NewsItemModel&gt;&gt; 我只是得到另一个错误将尝试 typealias,我使用的是 Moshi 而不是 GSON。
    • 对不起,我猜 Moshi 和 Gson 也有类似的错误信息。我提出的两种解决方案都是等效的。您确定在更新签名时收到相同的错误消息吗?
    • List&lt;NewsItemModel&gt; 出现什么错误?
    • 这很奇怪,我之前尝试过很多次但都失败了,或者我可能通过了不同的类型。无论如何,它现在只适用于Observable&lt;List&lt;NewsItemModel&gt;&gt;,所以我现在删除类NewsItemModels。但是,当我尝试Observable&lt;ArrayList&lt;NewsItemModel&gt;&gt; 时,它给出了一个错误java.lang.IllegalArgumentException: Unable to create converter for java.util.ArrayList&lt;com.app.app.NewsItemModel&gt; 这是为什么?
    • 也许 ArrayList 不是内置适配器之一:github.com/square/moshi#built-in-type-adaptersList 肯定在那里
    猜你喜欢
    • 2020-06-19
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    相关资源
    最近更新 更多