用于基元类型和数组的GSON自定义反序列化程序

xqkwcwgp  于 2022-11-06  发布在  其他
关注(0)|答案(3)|浏览(140)

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

"values": [
                    {
                        "type": "AAA",
                        "value": 3
                    },
                    {
                        "type": "BBB",
                        "value": [
                            {
                                "ABC": 8
                            },
                            {
                                "DEF": 9
                            },
                            {
                                "GHI": 9
                            },
                            {
                                "JKL": 8
                            },
                            {
                                "MNO": 9
                            },
                            {
                                "PQR": 9
                            }
                        ]
                    }
                ]

数据类别

data class Values(
    @SerializedName("type")
    @Expose
    val type: String,
    @SerializedName("value")
    @Expose
    val value: Int)

如您所见,value可以是Int或另一个Json数组。您知道如何为此编写反序列化器吗?Android应用程序当前正在使用Int字段(类型AAA),我正在尝试集成潜在的数组值(类型BBB)。谢谢。

dl5txlt9

dl5txlt91#

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

sealed class Value {
    /* type AAA */
    data class IntValue(val value: Int) : Value()
    /* type BBB */
    data class IntPairValue(val value: List<Pair<String, Int>>) : Value() 
}

并编写一个自定义反序列化程序:

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
    }
}

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

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访问您感兴趣的值。

erhoui1w

erhoui1w2#

请尝试使用此代码:

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();
        }
snz8szmq

snz8szmq3#

首先,在您的情况下,使用手动解析而不是自动解析,因为自动解析可能会出现问题,而且在这种情况下会有点复杂。现在您需要将请求更改为“JsonObject”。
请尝试以下代码...

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();
    }

希望,它起作用了。:)

相关问题