簡體   English   中英

如何使用 Kotlin 解析列表的 Retrofit 列表?

[英]How to parse Retrofit list of list with Kotlin?

我正在嘗試解析這種響應:

{
    "Data": [
        [
            {
                "Foo": "Foo",
                "Bar": "Bar"
            }
        ]
    ],
    "ResponseStatus": 1,
}

但是我無法讓它工作,調用服務時發生以下異常:

Failure(com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 10 path $.Data)

改造界面:

interface FooService {
    @GET("getFooData")
    suspend fun getFooData(
            @Query("foo") foo: String): Response<FooDto>
}

模型:

data class FooDto(
        val Data: List<List<FooItem>>,
        val ResponseStatus: Int
)

data class FooItem(
        val Foo: String,
        val Bar: String
)

這適用於只有 1 個列表的其他情況,但不適用於有列表列表的情況。

我測試了它,它工作得很好。 不過我用的是 Moshi,而不是 Gson。

data class response (
    @field:Json(name = "Data")val data: List<List<obj>>,
    @field:Json(name = "ResponseStatus")val status: Int
)

data class obj(
    @field:Json(name = "Foo") val foo: String,
    @field:Json(name = "Bar") val bar: String
)


val str = """{
    "Data": [
        [
            {
                "Foo": "Foo",
                "Bar": "Bar"
            }
        ]
    ],
    "ResponseStatus": 1
}""".trimIndent()

        val moshi = Moshi.Builder().build()
        val jsonAdapter = moshi.adapter(response::class.java)
        val parsed = jsonAdapter.fromJson(str)
        println(parsed)

我已經使用 Gson 進行了測試,它按預期工作。

依賴項:

    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

從包含您提供給我們的示例的 json 文件中讀取單元測試:

class ExampleUnitTest {



    @Test
    fun getGson() {


        val rawJson = JsonUnitTest().readJSONFromAsset("test.json")
        val type = object : TypeToken<FooDto>() {}.type
        val fooDto = Gson().fromJson<FooDto>(
            rawJson,
            type
        )


        assertEquals(fooDto.Data[0][0].Bar, "Bar")
        assertEquals(fooDto.Data[0][0].Foo, "Foo")

    }
}


data class FooDto(
    val Data: List<List<FooItem>>,
    val ResponseStatus: Int
)

data class FooItem(
    val Foo: String,
    val Bar: String
)


class JsonUnitTest(){


    fun readJSONFromAsset(fileName: String): String? {
        var json: String? = null
        json = try {
            val inputStream: InputStream = javaClass.classLoader!!.getResourceAsStream("api-response/$fileName")
            inputStream.bufferedReader().use{it.readText()}
        } catch (ex: IOException) {
            ex.printStackTrace()
            return null
        }
        return json
    }
}

使用 Gson 解析得很好。

        val response =
"""{
    "Data": [
        [
            {
                "Foo": "Foo",
                "Bar": "Bar"
            }
        ]
    ],
    "ResponseStatus": 1
}"""
        val dto = Gson().fromJson(response, FooDto::class.java)
        Log.d("test", "Parsed: $dto")

日志輸出:

Parsed: FooDto(Data=[[FooItem(Foo=Foo, Bar=Bar)]], ResponseStatus=1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM