使用Moshi从JSON中解析内部映射

4

我正在尝试使用Moshi解析以下JSON,但是无法解析像USA或UK这样的动态数据。 USAUK是动态键。

 {
"USA": {
    "name": "United State of America",
    "code": "US"
},
"UK": {
    "name": "United Kingdom",
    "code": "UK"
},
  "soft_update": "500",
  "hard_update": "500"
}

数据类:

data class ApiAppUpdate(val countryMap: Map<String, ApiCountry>,
                     @field:Json(name = "hard_update")
                     val forceUpdateVersion: Int,
                     @field:Json(name = "soft_update")
                     val softUpdateVersion: Int)

以下是我的JSON适配器代码:
fun getConfig(){
     val adapter: JsonAdapter<ApiAppUpdate> = moshi.adapter(ApiAppUpdatee::class.java)
}

我得到了软件和硬件更新的值,但countryMap始终为空。我不确定这里有什么问题。可以有人帮忙吗?谢谢。

1个回答

3
问题在于您的模型描述与此 JSON 匹配,而不是您附加的那个:
{
   "countryMap":{
      "USA":{
         "name":"United State of America",
         "code":"US"
      },
      "UK":{
         "name":"United Kingdom",
         "code":"UK"
      }
   },
   "soft_update":"500",
   "hard_update":"500"
}

在你的示例中,"USA""UK""soft_update""hard_update"处于同一级别。 更新: 这是一个可行的解决方案:
data class ApiCountry(val name: String, val code: String)

data class ApiAppUpdate(
    val countryMap: Map<String, ApiCountry>,
    @field:Json(name = "hard_update")
    val forceUpdateVersion: Int,
    @field:Json(name = "soft_update")
    val softUpdateVersion: Int
)

class ApiUpdateAdapter {

    @FromJson
    fun fromJson(reader: JsonReader): ApiAppUpdate {
        var forceUpdateVersion: Int = -1
        var softUpdateVersion: Int = -1
        val map: MutableMap<String, ApiCountry> = mutableMapOf()

        reader.beginObject()
        while (reader.hasNext()) {
            when (reader.peek()) {
                JsonReader.Token.NAME ->
                    when (val fieldName = reader.nextName()) {
                        "hard_update" -> forceUpdateVersion = reader.nextInt()
                        "soft_update" -> softUpdateVersion = reader.nextInt()
                        else -> {
                            reader.beginObject()
                            var name = ""
                            var code = ""
                            while (reader.hasNext()) {
                                when (reader.nextName()) {
                                    "name" -> name = reader.nextString()
                                    "code" -> code = reader.nextString()
                                    else -> reader.skipValue()
                                }
                            }
                            reader.endObject()
                            map[fieldName] = ApiCountry(name, code)
                        }
                    }
                else -> reader.skipValue()
            }
        }
        reader.endObject()

        return ApiAppUpdate(map, forceUpdateVersion, softUpdateVersion)
    }
}

fun main() {
    val sourceJson =
        "{\"USA\":{\"name\":\"United States of America\",\"code\":\"US\"},\"UK\":{\"name\":\"United Kingdom\",\"code\":\"UK\"}" +
                ",\"soft_update\":\"200\",\"hard_update\":\"300\"}"

    val adapter = Moshi.Builder()
        .add(ApiUpdateAdapter())
        .build()
        .adapter(ApiAppUpdate::class.java)

    val apiAppUpdate = adapter.fromJson(sourceJson)

    println(apiAppUpdate)
}

谢谢回复。有没有关于更改模型描述或JsonAdapter的建议,以使其按照提供的JSON工作!! - user1288005
谢谢 @adrianbukros。 - user1288005

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接