Вызов вторичного конструктора в модели ответа API в Kotlin Android - PullRequest
2 голосов
/ 07 мая 2020

Мой JSON Ответ выглядит как -

{
    "body": {
        "count": 4,
        "sender": "margarete20181570"
    },
    "inserted_at": "2020-05-07T05:48:14.465Z",
    "type": 1
},
{
    "body": "savanna19562530 hit the SOS button!",
    "inserted_at": "2020-05-06T09:17:36.658Z",
    "type": 2
}

И я использую класс данных, как показано ниже, для анализа JSON выше, что здесь не так!

data class Notification(val body: String, val inserted_at: String, val type: Int) {

constructor(
    msgBody: MessageNotification,
    inserted_at: String,
    type: Int
) : this(msgBody.sender + "Sent you " + msgBody.count + "Messages", inserted_at, type)

}

Но эта работа не приводит к ошибке синтаксического анализа, например - Expected String , got object

Мой вызов Api выглядит так:

@GET("notifications")
suspend fun getNotifications(
    @HeaderMap headers: HashMap<String, String>
): Response<List<Notification>>

Основная цель заключается в том, как чтобы переделать код таким образом, чтобы другой конструктор Notification модельного класса был вызван в разных случаях, чтобы он не выдавал такой ошибки expecting string, got object или expecting object got string

Как мне улучшить свой код для синтаксического анализа ответа?

Любая помощь приветствуется!

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Поскольку вы десериализуете JSON вручную, это может быть решением, которое вы можете попробовать

data class Body(val count: Int, val sender: String)

data class Notification(val body: Any, val insertedAt: String, val type: Int)

Теперь, анализируя ответ JSON

val jsonResponse = JSONArray(/*JSON response string*/) // I am guessing this is an array

    (0 until jsonResponse.length()).forEach {
        val jsonObj = jsonResponse.getJSONObject(it)
        val jsonBody = jsonObj.get("body")
        if (jsonBody is String) {
            // Body field is a String instance
            val notification = Notification(
                body = jsonBody.toString(),
                insertedAt = jsonObj.getString("inserted_at"),
                type = jsonObj.getInt("type")
            )
            // do something
        } else {
            // Body field is a object
            val jsonBodyObj = jsonObj.getJSONObject("body")
            val body = Body(
                count = jsonBodyObj.getInt("count"),
                sender = jsonBodyObj.getString("sender")
            )
            val notification = Notification(
                body = body,
                insertedAt = jsonObj.getString("inserted_at"),
                type = jsonObj.getInt("type")
            )

            // do something
        }
    }

Надеюсь, что это помогает или, по крайней мере, вы понимаете, как вы подходите к решению своей проблемы. Вы также можете проверить стратегию исключения Gson.

0 голосов
/ 07 мая 2020

Поле body в вашем JSON является объектом и должно отображаться на объект, определенный в вашем проекте. Для этой цели у вас может быть заголовок класса, подобный следующему:

data class Body(val count: Int, val sender: String)

Заголовок вашего класса Notification будет иметь поле Body для захвата этой части вашего ответа JSON следующим образом:

data class Notification(val body: Body, val inserted_at: String, val type: Int)

Обычно я использую Gson для десериализации откликов на модернизацию. Он работает очень хорошо, и его легко настроить. Дайте мне знать, если что-то нуждается в разъяснении.

...