使用 Gson 将 JSON 转换为带有对象的 HashMap

Der*_*son 2 java android json gson kotlin

在我的 Android 应用程序(用 Kotlin 编写)中,我需要将一些 JSON 转换为 MainObject 哈希映射的字符串。JSON 如下所示:

\n\n
{\n    "a": {\n        "name": "A",\n        "some_int": "2",\n        "some_string": "string",\n        "some_bool": false,\n        "some_string_arr": [\n            "str1",\n            "str2"\n        ],\n        "sub_obj_arr": [\n            {\n                "obj_name": "d",\n                "some_obj_string": "s"\n            }\n        ]\n    },\n    "b": {\n        "name": "B",\n        "some_int": "4",\n        "some_string": "string",\n        "some_bool": false,\n        "some_string_arr": [\n            "str5",\n            "str6"\n        ]\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我创建了几个对象来帮助解决这个问题。

\n\n
class MainObject {\n    @SerializedName("name")\n    val name: String? = null\n\n    @SerializedName("some_int")\n    val someInt: Int? = null\n\n    @SerializedName("some_string")\n    val someString: String? = null\n\n    @SerializedName("some_bool")\n    val someBool: Boolean = false\n\n    @SerializedName("some_string_arr")\n    val someStringArr: List<String>? = null\n\n    @SerializedName("sub_obj_arr")\n    val someObjArr: List<SubObject>? = null\n}\n\nclass SubObject {\n    @SerializedName("obj_name")\n    val objName: String? = null\n\n    @SerializedName("some_obj_string")\n    val someObjString: String? = null\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我如何将其转换为 的类型HashMap<String, MainObject>我尝试使用此处描述的 TypeToken ,但收到错误“预期开始对象但是字符串”。

\n\n

有任何想法吗?

\n\n

更新

\n\n

我还通过此处描述的解决方案在本地读取 JSON 数据

\n\n

错误日志

\n\n
10-15 20:06:42.771 10328-10328/xxx E/AndroidRuntime: FATAL EXCEPTION: main\n    Process: xxx, PID: 10328\n    java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)\n        at android.app.ActivityThread.-wrap11(Unknown Source:0)\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)\n        at android.os.Handler.dispatchMessage(Handler.java:105)\n        at android.os.Looper.loop(Looper.java:164)\n        at android.app.ActivityThread.main(ActivityThread.java:6541)\n        at java.lang.reflect.Method.invoke(Native Method)\n        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)\n     Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $\n        at com.google.gson.Gson.fromJson(Gson.java:900)\n        at com.google.gson.Gson.fromJson(Gson.java:853)\n        at com.google.gson.Gson.fromJson(Gson.java:802)\n        at xxx.onCreate(BottomNavigation.kt:48)\n        at android.app.Activity.performCreate(Activity.java:6975)\n        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)\xc2\xa0\n        at android.app.ActivityThread.-wrap11(Unknown Source:0)\xc2\xa0\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)\xc2\xa0\n        at android.os.Handler.dispatchMessage(Handler.java:105)\xc2\xa0\n        at android.os.Looper.loop(Looper.java:164)\xc2\xa0\n        at android.app.ActivityThread.main(ActivityThread.java:6541)\xc2\xa0\n        at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)\xc2\xa0\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)\xc2\xa0\n     Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $\n        at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)\n        at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:183)\n        at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)\n        at com.google.gson.Gson.fromJson(Gson.java:888)\n        at com.google.gson.Gson.fromJson(Gson.java:853)\xc2\xa0\n        at com.google.gson.Gson.fromJson(Gson.java:802)\xc2\xa0\n        at xxx.onCreate(BottomNavigation.kt:48)\xc2\xa0\n        at android.app.Activity.performCreate(Activity.java:6975)\xc2\xa0\n        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)\xc2\xa0\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)\xc2\xa0\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)\xc2\xa0\n        at android.app.ActivityThread.-wrap11(Unknown Source:0)\xc2\xa0\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)\xc2\xa0\n        at android.os.Handler.dispatchMessage(Handler.java:105)\xc2\xa0\n        at android.os.Looper.loop(Looper.java:164)\xc2\xa0\n        at android.app.ActivityThread.main(ActivityThread.java:6541)\xc2\xa0\n        at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)\xc2\xa0\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新2

\n\n

实际问题是我在本地 JSON 文件中读取的方式有问题。我使用的代码是这样的:

\n\n
val input = this.resources.openRawResource(R.raw.json)\nval json = try {\n    val size = input.available()\n    val buffer = ByteArray(size)\n    input.read(buffer)\n    input.close()\n    String(buffer)\n} catch (ex: IOException) {\n    ex.printStackTrace()\n    null\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我将 json 打印到控制台时,这给了我这些奇怪的字符:

\n\n

10-15 23:55:11.911 3351-3351/xxx I/System.out: \xef\xbf\xbd\xef\xbf\xbd{\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd

\n\n

10-15 23:55:11.911 3351-3351/xxx I/System.out: \xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\ xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd"\xef\xbf\xbd\xef\xbf\xbda\xef\xbf\xbd\xef \xbf\xbd"\xef\xbf\xbd\xef\xbf\xbd:\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd{\xef\xbf\xbd\ xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd

\n\n

但不知道为什么。

\n

Jos*_*hua 10

我不知道你为什么有任何错误。我可以使用以下代码解析 JSON。

val gson = GsonBuilder().create()
val type = object:TypeToken<Map<String, MainObject>>(){}.type
val result = gson.fromJson<Map<String, MainObject>>("{ \"a\": { \"name\": \"A\", \"some_int\": \"2\", \"some_string\": \"string\", \"some_bool\": false, \"some_string_arr\": [ \"str1\", \"str2\" ], \"sub_obj_arr\": [ { \"obj_name\": \"d\", \"some_obj_string\": \"s\" } ] }, \"b\": { \"name\": \"B\", \"some_int\": \"4\", \"some_string\": \"string\", \"some_bool\": false, \"some_string_arr\": [ \"str5\", \"str6\" ] } }", type)
Run Code Online (Sandbox Code Playgroud)