使用 kotlin.serialization 在偏移量 0 处获取意外的 json 标记

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

尝试从here解析json字符串,但是kotlin序列化抛出此错误:

kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 0: Expected beginning of the string, but got { at path: $JSON input: {"events":[{"id":1

使用此函数通过复古方式获取 json 字符串:

@GET("bootstrap-static")
suspend fun getBootstrapJson(): String

然后使用此函数在自定义 json 转换器对象中进行转换:

fun convert(string: String): BootStrapModel{
    return Json{ignoreUnknownKeys = true}.decodeFromString(string)
}

引导带模型定义如下:

@Serializable
data class BootStrapModel(
    @SerialName("events") val events: List<Events>,
    @SerialName("game_settings") val gameSettings: GameSettings,
    val phases: List<Phases>,
    val teams: List<Team>,
    @SerialName("total_players") val totalPlayers: Int,
    val players: List<Player>,
    @SerialName("element_stats") val elementStats: List<ElementStats>,
    @SerialName("element_types") val elementTypes: List<ElementTypes>,
)

这里的所有自定义数据类型都是可序列化的数据类,其中包含我想要的数据。 感谢任何帮助。

kotlin retrofit2 json-deserialization
1个回答
0
投票

我相信发生这种情况是因为您正在从

@GET
挂起函数调用 -
getBootstrapJson(): String
请求字符串结果。该错误告诉您字符串是您请求的预期响应类型,但它实际上返回一个 JSON 对象。您收到的 JSON 显示它是一个对象(大括号“{”),然后您就有一个标题为 events 的对象数组:

{
    "events": [
        {
            "id": 1 

因此,您应该请求一个包含事件列表的对象,例如

,而不是在 Retrofit 挂起函数中请求字符串
suspend fun getBootstrapJson(): BootStrapModel

然后必须将 JSON 对象转换为 Kotlin 对象,方法是首先将对象转换为字符串 (stringify),然后使用 Json.decodeToString() 映射到您的 Kotlin 对象。

您也可以使用 GSON 转换器 -

implementation("com.google.code.gson:gson:2.10.1")
...

 private val retrofit: Retrofit = Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        ...

它将根据您的模型解析对象,而不需要将其转换为字符串:

示例模型:

   data class BootStrapModel(
        @SerializedName("events") 
        val events: List<Event> // Request for a list of Event objects
        ...
    )

    data class Event(
        @SerializedName("id")
        val id: Long,
        @SerializedName("name")
        ...
    )

    data class ChipPlay (
        @SerializedName("chip_name")
        val chipName: ChipName,
        @SerializedName("num_played")
        val numPlayed: Long
    )
        ...

有一些网站,例如 https://app.quicktype.io/,您可以在其中放置 JSON 的副本,它将生成所需的 Kotlin 类。您还可以将插件下载到 Android studio,以便在程序文件中创建类: https://plugins.jetbrains.com/plugin/9960-json-to-kotlin-class-jsontokotlinclass-

© www.soinside.com 2019 - 2024. All rights reserved.