预期 BEGIN_OBJECT 但在路径 $ 处是 BEGIN_ARRAY - 使用 RxJava 处理 JSONArray 响应的 Retrofit2
Posted
技术标签:
【中文标题】预期 BEGIN_OBJECT 但在路径 $ 处是 BEGIN_ARRAY - 使用 RxJava 处理 JSONArray 响应的 Retrofit2【英文标题】:Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $ - Retrofit2 with RxJava handling JSONArray response 【发布时间】: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 代码。这里缺少什么?
【问题讨论】:
【参考方案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<List<NewsItemModel>>
我只是得到另一个错误将尝试 typealias,我使用的是 Moshi 而不是 GSON。
对不起,我猜 Moshi 和 Gson 也有类似的错误信息。我提出的两种解决方案都是等效的。您确定在更新签名时收到相同的错误消息吗?
List<NewsItemModel>
出现什么错误?
这很奇怪,我之前尝试过很多次但都失败了,或者我可能通过了不同的类型。无论如何,它现在只适用于Observable<List<NewsItemModel>>
,所以我现在删除类NewsItemModels
。但是,当我尝试Observable<ArrayList<NewsItemModel>>
时,它给出了一个错误java.lang.IllegalArgumentException: Unable to create converter for java.util.ArrayList<com.app.app.NewsItemModel>
这是为什么?
也许 ArrayList
不是内置适配器之一:github.com/square/moshi#built-in-type-adapters 和 List
肯定在那里以上是关于预期 BEGIN_OBJECT 但在路径 $ 处是 BEGIN_ARRAY - 使用 RxJava 处理 JSONArray 响应的 Retrofit2的主要内容,如果未能解决你的问题,请参考以下文章
预期 BEGIN_OBJECT 但在第 1 行第 1 列路径为 STRING - Laravel 到改造 2
获得错误预期BEGIN_ARRAY但在第1行第2列路径$是BEGIN_OBJECT
改造后请求错误 - java.lang.IllegalStateException: 预期 BEGIN_OBJECT 但在第 1 行第 1 列路径 $
AsyncTask 预期为 BEGIN_OBJECT,但在第 1 行第 2 列路径 $ 处为 BEGIN_ARRAY
Retrofit2 Android:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 $ 处为 BEGIN_OBJECT
更改我的程序接受文件的方式将从GSON创建此错误:预期BEGIN_ARRAY但在第1行第2列路径$ BEGIN_OBJECT?