You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GSON将JSON字符串转为Map<String,Any>时嵌套对象转JSONObject的方案

解决方案

问题原因

你当前使用TypeToken<HashMap<String, Any>>作为解析类型时,GSON默认会递归解析所有嵌套JSON结构,把嵌套对象统一转为LinkedHashMap类型,因此会自动完成深度解析,不符合你的需求。

可选实现方案

方案1:手动遍历根层级属性组装Map(最直观,无额外配置)

先将JSON字符串解析为GSON自带的JsonObject结构,仅遍历第一层键值对自行组装Map<String, Any>,嵌套结构直接转成你需要的JSONObject/JSONArray即可,代码示例:

import com.google.gson.Gson
import com.google.gson.JsonObject
import org.json.JSONObject
import org.json.JSONArray

fun jsonToMap(jsonStr: String?): Map<String, Any>? {
    return jsonStr?.let {
        val rootJsonObject = Gson().fromJson(it, JsonObject::class.java)
        val resultMap = HashMap<String, Any>()
        rootJsonObject.entrySet().forEach { entry ->
            val key = entry.key
            val value = entry.value
            when {
                value.isJsonPrimitive -> {
                    val primitive = value.asJsonPrimitive
                    when {
                        primitive.isString -> resultMap[key] = primitive.asString
                        primitive.isBoolean -> resultMap[key] = primitive.asBoolean
                        primitive.isNumber -> resultMap[key] = primitive.asNumber
                    }
                }
                value.isJsonObject -> resultMap[key] = JSONObject(value.toString())
                value.isJsonArray -> resultMap[key] = JSONArray(value.toString())
                value.isJsonNull -> resultMap[key] = Any() // 可根据需求调整null值处理逻辑
            }
        }
        resultMap
    }
}

方案2:自定义TypeAdapter适配解析规则

如果需要复用逻辑,可以为GSON注册自定义的TypeAdapter,专门处理Any类型的解析逻辑,遇到嵌套对象时直接返回JSONObject,代码示例:

import com.google.gson.GsonBuilder
import com.google.gson.TypeAdapter
import com.google.gson.reflect.TypeToken
import org.json.JSONObject

// 自定义Any类型的适配器
val anyTypeAdapter = object : TypeAdapter<Any>() {
    override fun write(out: com.google.gson.stream.JsonWriter?, value: Any?) {
        // 按需实现序列化逻辑,无序列化需求可留空
    }

    override fun read(`in`: com.google.gson.stream.JsonReader?): Any {
        `in`?.beginObject()
        val sb = StringBuilder()
        var level = 1
        while (level > 0) {
            val token = `in`?.peek()
            when (token) {
                com.google.gson.stream.JsonToken.BEGIN_OBJECT -> {
                    sb.append("{")
                    `in`.beginObject()
                    level++
                }
                com.google.gson.stream.JsonToken.END_OBJECT -> {
                    sb.append("}")
                    `in`.endObject()
                    level--
                }
                // 其余token按需拼接字符串,最后转成JSONObject即可
                // 省略其余类型判断的实现代码,可参考方案1的类型判断逻辑
            }
        }
        return JSONObject(sb.toString())
    }
}

// 构建自定义GSON实例
val customGson = GsonBuilder()
    .registerTypeAdapter(Any::class.java, anyTypeAdapter)
    .create()

// 使用时直接调用即可
fun jsonToMap(jsonStr: String?): Map<String, Any>? {
    return jsonStr?.let {
        customGson.fromJson(it, object : TypeToken<HashMap<String, Any>>() {}.type)
    }
}

推荐优先使用方案1,逻辑清晰可控,不需要额外适配GSON的序列化/反序列化规则,出现问题排查成本更低。

内容的提问来源于stack exchange,提问作者HyperX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 17:06:02