首页 > 解决方案 > 如何在 Kotlin 中创建正确的 JSON 类(用于 Fuel)

问题描述

我有一个返回 JSON 的请求:

{
  "success": 0,
  "errors": {
    "phone": [
      "Incorrect phone number"
    ]
  }
}

我为 Kotlin 插入了 Fuel 而不是 Retrofit。所以,我的课是:

data class RegistrationResponse(
    val success: Int,
    val errors: RegistrationErrorsResponse?) {

    class Deserializer : ResponseDeserializable<RegistrationResponse> {
        override fun deserialize(content: String): RegistrationResponse? =
            Gson().fromJson(content, RegistrationResponse::class.java)
    }
}

data class RegistrationErrorsResponse(val phone: List<String>?) {

    class Deserializer : ResponseDeserializable<RegistrationErrorsResponse> {
        override fun deserialize(content: String): RegistrationErrorsResponse? =
            Gson().fromJson(content, RegistrationErrorsResponse::class.java)
    }
}

请求如下所示:

class Api {

    init {
        FuelManager.instance.basePath = SERVER_URL
    }

    fun registration(name: String, phone: String): Request =
        "/registration/"
            .httpPost(listOf("name" to name, "phone" to phone))
}

private fun register(name: String, phone: String) {
    Api().registration(name, phone)
        .responseObject(RegistrationResponse.Deserializer()) { _, response, result ->
            val registrationResponse = result.component1()
            if (registrationResponse?.success == 1) {
                showScreen()
            } else {
                showErrorDialog(registrationResponse?.errors?.phone?.firstOrNull())
            }
        }
}

一个问题是,当发生错误时,phone数据类 (registrationResponse?.errors?.phone) 中的变量填充为null,而不是“不正确的电话号码”。

标签: androidjsonkotlin

解决方案


在搜索了 Fuel 问题后,我了解到在大多数情况下,我们不需要编写自己的反序列化器,因为它们已经由Gson.

https://github.com/kittinunf/Fuel/issues/265中有一个例子。因此,只需将您的数据类放入<>

URL.httpPost(listOf("name" to name, "phone" to phone)).responseObject<RegistrationResponse> ...

并通过

result.component1()?.errors?.phone?.firstOrNull()

旧版答案

可能一个障碍是列表反序列化,请参见
1. https://github.com/kittinunf/Fuel/issues/233
2. https://github.com/kittinunf/Fuel/pull/236

我认为,默认情况下,Fuel 不使用 Gson 反序列化。

我仍然不知道如何反序列化一个列表,但是用这个表达式得到了值:

((result.component1().obj()["errors"] as JSONObject).get("phone") as JSONArray)[0]

推荐阅读