首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基元类型和数组的GSON自定义反序列化器

基元类型和数组的GSON自定义反序列化器
EN

Stack Overflow用户
提问于 2021-09-03 11:48:00
回答 3查看 214关注 0票数 0

我有一个可能具有不同值的JSON响应。

代码语言:javascript
复制
"values": [
                    {
                        "type": "AAA",
                        "value": 3
                    },
                    {
                        "type": "BBB",
                        "value": [
                            {
                                "ABC": 8
                            },
                            {
                                "DEF": 9
                            },
                            {
                                "GHI": 9
                            },
                            {
                                "JKL": 8
                            },
                            {
                                "MNO": 9
                            },
                            {
                                "PQR": 9
                            }
                        ]
                    }
                ]

数据类

代码语言:javascript
复制
data class Values(
    @SerializedName("type")
    @Expose
    val type: String,
    @SerializedName("value")
    @Expose
    val value: Int)

如您所见,value可以是Int,也可以是另一个Json。有什么想法吗?如何编写反序列化器?Android应用程序目前正在使用Int字段(AAA类型),我正在尝试集成潜在的Array值(类型为BBB)。谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-09-03 19:48:11

例如,您可以有一个带有两个子类的密封类Value

代码语言:javascript
复制
sealed class Value {
    /* type AAA */
    data class IntValue(val value: Int) : Value()
    /* type BBB */
    data class IntPairValue(val value: List<Pair<String, Int>>) : Value() 
}

并编写自定义反序列化器:

代码语言:javascript
复制
class ValueTypeDeserializer : JsonDeserializer<Value?> {
    override fun deserialize(
        json: JsonElement,
        typeOfT: Type,
        context: JsonDeserializationContext
    ): Value? {
        return when {
            json.isJsonPrimitive -> {
                Value.IntValue(json.asJsonPrimitive.asInt)
            }
            json.isJsonArray -> {
                val list = context.deserialize<List<Map<String, Int>>>(json, LIST_OF_MAP_TYPE)
                val pairs = list.map { e -> e.firstNotNullOf { (key, value) -> Pair(key, value) } }
                Value.IntPairValue(pairs)
            }
            else -> null
        }
    }

    companion object {
        private val LIST_OF_MAP_TYPE = object : TypeToken<List<Map<String, Int>>>() {}.type
    }
}

现在,您可以使用"value"注释将反序列化器应用于@JsonAdapter字段,如下所示:

代码语言:javascript
复制
data class Values(
    @SerializedName("type")
    @Expose
    val type: String,
    @SerializedName("value")
    @Expose
    @JsonAdapter(ValueTypeDeserializer::class)
    val value: Value
) {
    val optIntValue: Int?
        get() = (value as? Value.IntValue)?.value
    val optIntPairValue: List<Pair<String, Int>>?
        get() = (value as? Value.IntPairValue)?.value
}

使用optIntValueoptIntPairValue访问您感兴趣的值。

票数 1
EN

Stack Overflow用户

发布于 2021-09-03 12:02:23

尝试使用以下代码:

代码语言:javascript
复制
        try {
            JSONObject jsonObject = new JSONObject(); // this is your values object
            Object o = jsonObject.get("value");
            if (o instanceof JSONArray) {
                //this is jsonarray
            } else if (o instanceof JSONObject) {
                //this is jsonobject
            } else if (o instanceof Integer) {
                //this is int
            } else if (o instanceof String) {
                //this is String
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
票数 -1
EN

Stack Overflow用户

发布于 2021-09-03 12:21:05

首先,在您的示例中,使用手动解析而不是自动解析,因为自动解析可能会出现问题,在本例中也会有些复杂。现在您需要将请求更改为"JsonObject“。

试试这个密码..。

代码语言:javascript
复制
try {
        JSONObject your_response=new JSONObject();

        JSONArray jsonArrayMain=your_response.getJSONArray("values");

        for (int i = 0; i < jsonArrayMain.length(); i++) {
            JSONObject jsonObject=jsonArrayMain.getJSONObject(i);
            String type=jsonObject.getString("type");

            Object o = jsonObject.get("value");
            if (o instanceof JSONArray) {
                //value is array
                JSONArray jsonArrayValue=jsonObject.getJSONArray("value");

                for (int j = 0; j <jsonArrayValue.length(); j++) {

                    JSONObject subJsonObject=jsonArrayValue.getJSONObject(j);
                    
                    Iterator<String> iterator = subJsonObject.keys();
                    while (iterator.hasNext()) {
                        String key = iterator.next();
                        Log.i("====TAG","key:"+key +"--Value::"+subJsonObject.optString(key);
                    }
                }

            } else if (o instanceof String) {
                //value is string
                String value=jsonObject.getString("value");
            }
        }

    }catch (Exception e){
        e.printStackTrace();
    }

霍普,成功了。:)

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69044412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档