在 Moshi 中解析来自 JSON 的内部映射
Parse internal map from JSON in Moshi
我正在尝试使用 moshi 解析以下 JSON,但我无法动态处理美国或英国等数据。 USA
和 UK
是动态键。
{
"USA": {
"name": "United State of America",
"code": "US"
},
"UK": {
"name": "United Kingdom",
"code": "UK"
},
"soft_update": "500",
"hard_update": "500"
}
数据class:
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 始终为空。我不确定这里出了什么问题。有人可以帮帮我吗。谢谢。
问题是您的模型描述会匹配此 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)
}
我正在尝试使用 moshi 解析以下 JSON,但我无法动态处理美国或英国等数据。 USA
和 UK
是动态键。
{
"USA": {
"name": "United State of America",
"code": "US"
},
"UK": {
"name": "United Kingdom",
"code": "UK"
},
"soft_update": "500",
"hard_update": "500"
}
数据class:
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 始终为空。我不确定这里出了什么问题。有人可以帮帮我吗。谢谢。
问题是您的模型描述会匹配此 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)
}