簡體   English   中英

如何使用 retrofit 和 moshi 解析換行符分隔的 JSON?

[英]How to parse newline delimited JSON with retrofit and moshi?

我正在嘗試使用 retrofit 和 moshi 解析換行符分隔的 json。 這是我的 GET function:

suspend fun getDeviceValuesNew(@Path("application-id") applicationId: String, @Path("device-id") deviceId: String) 
: Response<List<ValueApiResponse>>

當我嘗試運行它時,我收到此錯誤:

 com.squareup.moshi.JsonDataException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at path $

HTTP 調用返回 json,如下所示:

{
    "result": {
        "end_device_ids": {
            "device_id": "esp32",
            "application_ids": {}
        },
        "received_at": "2021-03-31T11:33:42.757281753Z",
        "uplink_message": {
            "decoded_payload": {
                "brightness": 0
            },
            "settings": {
                "data_rate": {}
            },
            "received_at": "2021-03-31T11:33:42.547285090Z"
        }
    }
}
{
    "result": {
        "end_device_ids": {
            "device_id": "esp32",
            "application_ids": {}
        },
        "received_at": "2021-03-31T11:18:17.745921472Z",
        "uplink_message": {
            "decoded_payload": {
                "brightness": 0
            },
            "settings": {
                "data_rate": {}
            },
            "received_at": "2021-03-31T11:18:17.538276218Z"
        }
    }
}

EDIT #1: As you can see in my answer below, I managed to get a valid JSON response from the API, but still I'm struggling to parse these JSON objects to a list of Kotlin objects. 如何讓 Moshi 將這些換行符分隔的 JSON 對象作為列表處理? 我認為問題在於 Moshi 要求將對象包裝在數組中才能被識別為列表。 我怎么做?

這是我用於解析的數據 class :

@JsonClass(generateAdapter = true)
data class ValueDto(
    @Json(name = "result")
    val result: Result
) {
    @JsonClass(generateAdapter = true)
    data class Result(
        @Json(name = "end_device_ids")
        val endDeviceIds: EndDeviceIds,
        @Json(name = "received_at")
        val receivedAt: String,
        @Json(name = "uplink_message")
        val uplinkMessage: UplinkMessage
    ) {
        @JsonClass(generateAdapter = true)
        data class EndDeviceIds(
            @Json(name = "application_ids")
            val applicationIds: ApplicationIds,
            @Json(name = "device_id")
            val deviceId: String
        ) {
            @JsonClass(generateAdapter = true)
            class ApplicationIds(
            )
        }

        @JsonClass(generateAdapter = true)
        data class UplinkMessage(
            @Json(name = "decoded_payload")
            val decodedPayload: DecodedPayload,
            @Json(name = "received_at")
            val receivedAt: String,
            @Json(name = "settings")
            val settings: Settings
        ) {
            @JsonClass(generateAdapter = true)
            data class DecodedPayload(
                @Json(name = "brightness")
                val brightness: Int
            )
            @JsonClass(generateAdapter = true)
            data class Settings(
                @Json(name = "data_rate")
                val dataRate: DataRate
            ) {
                @JsonClass(generateAdapter = true)
                class DataRate(
                )
            }
        }
    }
}

@tyczj 是對的,這不是有效的 ndjson,因為 ndjson 換行符僅出現在每個單獨的 json 文本之后。 解決方案是使用 HTTP 請求發送Accept: text/event-stream ,現在我得到一個有效的 ndjson 響應,如下所示:

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:19:04.021238048Z","uplink_message":{"decoded_payload":{"brightness":0},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:19:03.809173924Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:25:22.260712161Z","uplink_message":{"decoded_payload":{"brightness":119},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:25:22.046086937Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:18:58.438947740Z","uplink_message":{"decoded_payload":{"brightness":0},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:18:58.228671174Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:21:10.102303310Z","uplink_message":{"decoded_payload":{"brightness":106},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:21:09.893217735Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:23:16.177064041Z","uplink_message":{"decoded_payload":{"brightness":108},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:23:15.967959055Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:27:28.334312076Z","uplink_message":{"decoded_payload":{"brightness":117},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:27:28.126104222Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:29:34.400253264Z","uplink_message":{"decoded_payload":{"brightness":99},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:29:34.190980301Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:31:40.481766225Z","uplink_message":{"decoded_payload":{"brightness":118},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:31:40.270452429Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:33:46.567235913Z","uplink_message":{"decoded_payload":{"brightness":114},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:33:46.357373037Z"}}}

{"result":{"end_device_ids":{"device_id":"esp32-bh1750","application_ids":{}},"received_at":"2021-04-24T10:35:52.737386496Z","uplink_message":{"decoded_payload":{"brightness":121},"settings":{"data_rate":{}},"received_at":"2021-04-24T10:35:52.426583804Z"}}}

我已經通過 retrofit 注釋添加了 Header: @Headers("Accept: text/event-stream ")

暫無
暫無

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

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