使用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
相关产品推荐
相关产品推荐

