【问题标题】:Json same name different data type Moshi AndroidJson同名不同数据类型Moshi Android
【发布时间】:2020-12-18 19:37:43
【问题描述】:

这是我的模型类,我有这些类型的 json 可以转换成这个模型。我怎么能用 Moshi 做到这一点(使用改造)

data class(var Id:Int, var image:List<String>)

{"Id":188, "image":"\/posts\/5fd9aa6961c6dd54129f51d1.jpeg"}

{"Id":188, "image":["\/posts\/5fd9aa6961c6dd54129f51d1.jpeg","\/posts\/5fd9aa6961c6dd54129f51d1.jpeg"]}

【问题讨论】:

  • 您能否指定,如果两种类型的 JSON 由同一个请求返回,或者有 2 个单独的请求并且每个返回一种类型的 JSON?
  • 如果这些响应中的任何一个可以通过单个 API 调用实现,那么这将需要自定义序列化程序来检测类型,然后将其适当地格式化为适当的数据类。
  • 这两者都可以在单个请求中看到。您能否举一个自定义序列化程序的示例??
  • @SartajRoshan 检查我的答案

标签: android kotlin retrofit2 moshi


【解决方案1】:

您的情况有点不正统,一般来说,我会避免设计具有匹配字段名称但签名不同的 JSON。无论如何,解决方案:

如下定义您的模型:

data class MyModel(
    @Json(name = "Id") val Id: Long,
    @Json(name = "image") val images: List<String>
)

然后,您必须为其创建一个自定义适配器:

class MyModelAdapter {
    @ToJson
    fun toJson(model: MyModel): String {
        // MyModel is data class so .toString() should convert it to correct Json format with
        // image property as list of image path strings
        return model.toString()
    }

    @FromJson
    fun fromJson(reader: JsonReader): MyModel = with(reader) {
        // We need to manually parse the json
        var id: Long? = null
        var singleImage: String? = null
        val imageList = mutableListOf<String>()

        beginObject()
        while (hasNext()) {
            // iterate through the JSON fields
            when (nextName()) {
                "Id" -> id = nextLong() // map the id field
                "image" -> { // map the image field
                    when (peek()) {
                        JsonReader.Token.BEGIN_ARRAY -> {
                            // the case where image field is an array
                            beginArray()
                            while(hasNext()) {
                                val imageFromList = nextString()
                                imageList.add(imageFromList)
                            }
                            endArray()
                        }
                        JsonReader.Token.STRING -> {
                            // the case where image field is single string
                            singleImage = nextString()
                        }
                        else -> skipValue()
                    }
                }
                else -> skipValue()
            }
        }
        endObject()
        id ?: throw IllegalArgumentException("Id should not be null")
        val images = if (singleImage != null) {
            listOf(singleImage)
        } else {
            imageList
        }
        MyModel(Id = id, images = images)
    }
}

然后,将适配器添加到您的 moshi 构建器:

Moshi.Builder()
    .add(MyModelAdapter())
    .build()

应该这样做。有关完整的代码库,您可以查看我刚刚创建的与您的案例相符的演示:

https://github.com/phamtdat/MoshiMultipleJsonDemo

【讨论】:

    猜你喜欢
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多