如何使用 Gson 将 JSON 转换为 HashMap?
我正在从服务器请求数据,该服务器返回 JSON 格式的数据。在发出请求时将 HashMap 转换为 JSON 一点也不难,但另一种方法似乎有点棘手。 JSON 响应如下所示:
{
"header" : {
"alerts" : [
{
"AlertID" : "2",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
},
{
"AlertID" : "3",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
}
],
"session" : "0bc8d0835f93ac3ebbf11560b2c5be9a"
},
"result" : "4be26bc400d3c"
}
什么方式最容易访问此数据?我正在使用 GSON 模块。
I'm requesting data from a server which returns data in the JSON format. Casting a HashMap into JSON when making the request wasn't hard at all but the other way seems to be a little tricky. The JSON response looks like this:
{
"header" : {
"alerts" : [
{
"AlertID" : "2",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
},
{
"AlertID" : "3",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
}
],
"session" : "0bc8d0835f93ac3ebbf11560b2c5be9a"
},
"result" : "4be26bc400d3c"
}
What way would be easiest to access this data? I'm using the GSON module.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
干得好:
Here you go:
这段代码的工作原理:
This code works:
我知道这是一个相当老的问题,但我一直在寻找一种解决方案来将嵌套 JSON 反序列化为
Map
,但什么也没找到。我的 yaml 反序列化器的工作方式是,当您未指定类型时,它会将 JSON 对象默认为
Map
,但 gson 似乎没有这样做。幸运的是,您可以使用自定义解串器来完成它。我使用以下反序列化器自然地反序列化任何内容,将
JsonObject
默认为Map
并将JsonArray
默认为Object[ ]
s,其中所有子级都被类似地反序列化。handlePrimitive
方法内部的混乱是为了确保你只得到一个 Double 或一个 Integer 或一个 Long,并且可能会更好,或者至少简化如果你可以接受 BigDecimals,这我相信是默认的。您可以像这样注册这个适配器:
然后像这样调用它:
我不确定为什么这不是 gson 中的默认行为,因为它在大多数其他半结构化序列化库中......
I know this is a fairly old question, but I was searching for a solution to generically deserialize nested JSON to a
Map<String, Object>
, and found nothing.The way my yaml deserializer works, it defaults JSON objects to
Map<String, Object>
when you don't specify a type, but gson doesn't seem to do this. Luckily you can accomplish it with a custom deserializer.I used the following deserializer to naturally deserialize anything, defaulting
JsonObject
s toMap<String, Object>
andJsonArray
s toObject[]
s, where all the children are similarly deserialized.The messiness inside the
handlePrimitive
method is for making sure you only ever get a Double or an Integer or a Long, and probably could be better, or at least simplified if you're okay with getting BigDecimals, which I believe is the default.You can register this adapter like:
And then call it like:
I'm not sure why this is not the default behavior in gson, since it is in most other semi-structured serialization libraries...
使用 google 的 Gson 2.7(也可能是早期版本,但我使用当前版本 2.7 进行了测试),它非常简单:
返回
com.google.gson.internal.LinkedTreeMap< 类型的
Map
/code> 并在嵌套对象、数组等上递归地工作。我像这样运行了 OP 示例(只需用单引号替换 double- 并删除空格):
并得到以下输出:
With google's Gson 2.7 (probably earlier versions too, but I tested with the current version 2.7) it's as simple as:
Which returns a
Map
of typecom.google.gson.internal.LinkedTreeMap
and works recursively on nested objects, arrays, etc.I ran the OP example like so (simply replaced double- with single-quotes and removed whitespace):
And got the following output:
新 Gson 库更新:
现在,您可以直接将嵌套的 Json 解析为 Map,但您应该注意,如果您尝试将 Json 解析为
Map
类型:它会引发异常。要解决此问题,只需将结果声明为LinkedTreeMap
类型即可。下面的例子:Update for new Gson lib:
You now can parse nested Json to Map directly, but you should be aware in case you try to parse Json to
Map<String, Object>
type: it will raise exception. To fix this, just declare the result asLinkedTreeMap
type. Example below:我有完全相同的问题并最终来到这里。我有一种不同的方法,看起来更简单(也许是更新版本的 gson?)。
具有以下 json
以下
输出
您可以在导航 jsonObject 时使用 instanceof 动态检查。像
它对我有用,所以它一定对你有用;-)
I had the exact same question and ended up here. I had a different approach that seems much simpler (maybe newer versions of gson?).
with the following json
The following
outputs
You could dynamically check using instanceof when navigating your jsonObject. Something like
It works for me, so it must work for you ;-)
从 gson 2.8.0 开始支持以下内容
Below is supported since gson 2.8.0
试试这个,它会起作用的。我将它用于哈希表。
将 KioskStatusResource 替换为您的类,并将 Integer 替换为您的关键类。
Try this, it will worked. I used it for Hashtable.
Replace KioskStatusResource to your class and Integer to your key class.
这是我一直在使用的:
Here is what I have been using:
这是一个可以做到这一点的单行代码:
Here's a one-liner that will do it:
我已经使用自定义 JsonDeSerializer 克服了类似的问题。我试图让它变得更通用,但仍然不够。这是一个适合我的需求的解决方案。
首先,您需要为 Map 对象实现一个新的 JsonDeserializer。
反序列化方法看起来与此类似:
此解决方案的缺点是我的 Map 的键始终为“String”类型。然而,通过改变一些东西,有人可以使其通用。另外,我需要说的是,值的类应该在构造函数中传递。因此,我的代码中的方法
getMyType()
返回在构造函数中传递的 Map 值的类型。您可以参考这篇文章 How do I write a custom JSON Gson 的反序列化器? 以了解有关自定义反序列化器的更多信息。
I have overcome a similar problem with a Custom JsonDeSerializer. I tried to make it a bit generic but still not enough. It is a solution though that fits my needs.
First of all you need to implement a new JsonDeserializer for Map objects.
And the deserialize method will look similar to this:
The con with this solution, is that my Map's key is always of Type "String". However by chaning some things someone can make it generic. In addition, i need to say, that the value's class should be passed in the constructor. So the method
getMyType()
in my code returns the type of the Map's values, which was passed in the constructor.You can reference this post How do I write a custom JSON deserializer for Gson? in order to learn more about custom deserializers.
您可以使用此类来代替:)(甚至处理列表、嵌套列表和 json)
要将 JSON 字符串转换为 hashmap 使用以下代码:
You can use this class instead :) (handles even lists , nested lists and json)
To convert your JSON string to hashmap use this :
这更多的是 Kevin Dolan 的答案的附录,而不是完整的答案,但我在从数字中提取类型时遇到了麻烦。这是我的解决方案:
This is more of addendum to Kevin Dolan's answer than a complete answer, but I was having trouble extracting the type from the Number. This is my solution:
JSONObject 通常在内部使用
HashMap
来存储数据。因此,您可以在代码中将其用作 Map 。例子,
JSONObject typically uses
HashMap
internally to store the data. So, you can use it as Map in your code.Example,
我使用了这段代码:
I used this code: