如何使用Retrofit通过GSON从API解析JSON数组?

ubbxdtey  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(138)

嗨!
以下是API响应:

[
    {
        "id": 1,
        "name": "Facebook"
    },
    {
        "id": 2,
        "name": "Angry Birds"
    }
]

下面是我的Retrofit API声明:

@GET("/api/apps")
  suspend fun getApps(): Response<AppList<App>>

以下是我的App和AppList类:

class App(

    var id: Number,
    var name: String

    ) : Serializable
class AppList<App>(list: List<App>)

下面是我调用API的方式:

val response: Response<AppList<App>> = API.callBackend().getApplications()

这就是错误:

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

如何用GSON解析数组?我错过了什么?

E D I T:

如果我将所有AppList<App>更改为List<App>,则没有IllegalException,但我的App示例仍然绝对为空,这意味着idname都为null

camsedfj

camsedfj1#

只需对您的界面进行以下更改,看看它是否有效。

@GET("/api/apps")
  suspend fun getApps(): Response<ArrayList<App>>

像下面这样更改您的应用程序类。

data class App(
        @SerializedName("id")
        var id: Number,
        @SerializedName("name")
        var name: String
        ): Serializable
wz1wpwve

wz1wpwve2#

通过对代码进行一些调整,可以使用Gson和Retrofit从API解析JSON数组。你可以这样做:
1.更新您的Retrofit API声明:

@GET("/api/apps")
suspend fun getApps(): Response<List<App>>

这个变化告诉Retrofit期望一个JSON数组作为响应。
1.修改AppList类。不需要创建自定义的AppList类;可以直接使用List<App>作为响应类型。
1.确保App类具有无参数构造函数和正确命名的字段,以便Gson将JSONMap到对象。如果JSON名称不完全匹配,您可以使用注解来指定它们:

import com.google.gson.annotations.SerializedName

data class App(
    @SerializedName("id")
    val id: Int,

    @SerializedName("name")
    val name: String
)

通过这些更改,您的Retrofit服务接口、App类和API调用应该可以正常工作。以下是调用API的方法:

try {
    val response: Response<List<App>> = API.callBackend().getApps()

    if (response.isSuccessful) {
        val apps: List<App>? = response.body()
        if (apps != null) {
            for (app in apps) {
                // Handle each app here
                println("App ID: ${app.id}, Name: ${app.name}")
            }
        } else {
            // Handle null response
        }
    } else {
        // Handle the error response
    }
} catch (e: Exception) {
    // Handle exceptions
}

通过这些更改,Gson应该正确地将JSON数组响应解析为App对象列表。
希望这对你有帮助!

shyt4zoc

shyt4zoc3#

方法签名应如下所示:

interface ApiService {
   @GET("/api/apps")
   suspend fun getApps(): List<App>
}

App类应该如下所示:

data class App(val id: Long, val name: String)

像这样调用API:

class AppRepository(private val api: ApiService) {
    suspend fun getApps() {
        withContext(Dispaatchers.IO) {
            val apps = api.getApps();
            // perform operation with apps obtained from API
        }
     }
}

因为它是一个挂起函数,所以你不需要用像Response这样的响应对象来 Package 返回类型,Retrofit足够聪明,可以识别和解释类型。如果有任何错误,它将抛出异常而不是返回错误响应。
错误的原因是您的AppList类正在您的响应对象中查找list数组。对于您当前的AppList类,您的响应必须如下所示,以便成功验证。现在你明白为什么错误消息Expected BEGIN_OBJECT but was BEGIN_ARRAY是有意义的了。

{
   "list": [
    
    {
        "id": 1,
        "name": "Facebook"
    },
    {
        "id": 2,
        "name": "Angry Birds"
    }
  ]
}

相关问题