Json同名不同数据类型MoshiAndroid
Json same name different data type Moshi Android
这是我的模型 class,我有这些类型的 json 可以转换成这个模型。我如何使用 Moshi 做到这一点(使用 Retrofit)
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。无论如何,解决方案:
按如下方式定义您的模型:
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()
应该可以了。对于完整的代码库,您可以查看我刚刚创建的反映您的情况的演示:
这是我的模型 class,我有这些类型的 json 可以转换成这个模型。我如何使用 Moshi 做到这一点(使用 Retrofit)
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。无论如何,解决方案:
按如下方式定义您的模型:
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()
应该可以了。对于完整的代码库,您可以查看我刚刚创建的反映您的情况的演示: