如何使用纯 Kotlin 序列化反序列化动态 Json

3

我正在研究在我的最新项目中使用Kotlin序列化的方法。

我需要处理的Json如下:

{
    "countryCodeMapping": {
        "ssd": [
            {
                "name": "South Sudan",
                "alpha2": "ss",
                "alpha3": "ssd"
            }
        ],
        "nic": [
            {
                "name": "Nicaragua",
                "alpha2": "ni",
                "alpha3": "nic"
            }
        ],
        "fin": [
            {
                "name": "Finland",
                "alpha2": "fi",
                "alpha3": "fin"
            }
        ],
        "cck": [
            {
                "name": "Cocos (Keeling) Islands",
                "alpha2": "cc",
                "alpha3": "cck"
            }
        ],
        "tun": [
            {
                "name": "Tunisia",
                "alpha2": "tn",
                "alpha3": "tun"
            }
        ],
        "uga": [
            {
                "name": "Uganda",
                "alpha2": "ug",
                "alpha3": "uga"
            }
        ],
....
        "myDescriptions": {
        "1": {
            "groupId": 1,
            "description": "cvbxcvbxcvbxbxb",
            "myTypes": [
                "cxcvbxb",
                "xcvxcbxxx",
                "cvbxcvbxcxvcb"
            ]
        },
        "2": {
            "groupId": 2,
            "description": "vxvbxbxbxbx",
            "myTypes": [
                "xcvb",
                "xcvbxcvb"
            ]
        },
        "3": {
            "groupId": 3,
            "description": "xcvbxcvbxcvbxcvb",
            "myTypes": [
                "xcvbxcvbxcvbx"
            ]
        },
        "4": {
            "groupId": 4,
            "description": "xcvbxcbxcvbxcb",
            "myTypes": [
                "xcvbxcxcvb"
            ]
        },
        "5": {
            "groupId": 5,
            "description": "xcvbxcvbxcvbxcvbx",
            "myTypes": [
                "xcvbxcvbxc",
                "xcvbxcvbxcvbxb"
            ]
        },
        "6": {
            "groupId": 6,
            "description": "dfgsdfgsdgsdfgsdgsg",
            "myTypes": [
        

我必须解码整个Json字符串,但是我从以下countryCodeMapping

部分开始:

@Serializable
data class Meta(

    @SerialName("countryCodeMapping")
    val mapping: CountryCodeMapping
)

@Serializable
data class CountryCodeMapping(val ssd: List<Country>)

@Serializable
data class Country(

    @SerialName("name")
    val name: String,

    @SerialName("alpha2")
    val alpha2: String,

    @SerialName("alpha3")
    val alpha3: String
)


val countryMap: Meta = Json {
    isLenient = true
    ignoreUnknownKeys = true
    allowStructuredMapKeys = true
}.decodeFromString<Meta>(metaJson)

这个可以工作,但是我只解码了苏丹。

countryMap = Meta(mapping=CountryCodeMapping(ssd=[Country(name=South Sudan, alpha2=ss, alpha3=ssd)]))

我需要哪些数据类模型才能实现我的目标?

更新

我需要做出的更改(基于答案评论)是:

@Serializable
data class Meta(

    @SerialName("countryCodeMapping")
    val mapping: Map<String, List<Country>>
)

@Serializable
data class Country(

    @SerialName("name")
    val name: String? = null,

    @SerialName("alpha2")
    val alpha2: String? = null,

    @SerialName("alpha3")
    val alpha3: String? = null
)
2个回答

3
您可以在此处使用常规地图:
val mapping: Map<String, List<Country>>

当我尝试使用以下代码时: val mapping: Map<String, List<Country>> = Json { isLenient = true ignoreUnknownKeys = true allowStructuredMapKeys = true }.decodeFromString(metaJson) 我遇到了这个异常... Exception in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 21: Expected start of the array '[', but had ':' instead JSON input: {"countryCodeMapping":{"ssd":[{"name":"South Sudan"..... - undefined
еҸӘжҳҜдёәдәҶжҫ„жё…дёҖдёӢпјҢMap<String, List<Country>> еә”иҜҘдҪңдёә CountryCodeMapping зұ»еһӢзҡ„жӣҝд»ЈпјҢе…¶дҪҷйғЁеҲҶеҸҜд»Ҙдҝқз•ҷгҖӮ - undefined

2
当你有像 { "someKey": ..., "otherKey": ... } 这样的JSON对象时,你主要有两种选项来表示它们:
  1. 使用具有属性的常规类
  2. 使用通用的 Map<String, ...>
你当前的方法使用选项1(使用 CountryCodeMapping 类和硬编码的 ssd 属性)。当键是固定且已知的时,这种方法最好。
当键是动态的并且所有值都具有相同的类型时,选项2更好,而这正是你在这里的情况。
为了实现选项2,请使用 @broot 建议的 Map<String, List<Country>> 而不是 CountryCodeMapping 类:
@Serializable
data class Meta(

    @SerialName("countryCodeMapping")
    val mapping: Map<String, List<Country>>
)

@Serializable
data class Country(

    @SerialName("name")
    val name: String,

    @SerialName("alpha2")
    val alpha2: String,

    @SerialName("alpha3")
    val alpha3: String
)

非常感谢你的帮助,最终我找到了解决方法:), 现在我可以开始解析同一段JSON中的其他对象了。 - undefined

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