如何迭代JsonObject(gson)

17

我有一个 JsonObject,例如

JsonObject jsonObject = {"keyInt":2,"keyString":"val1","id":"0123456"}

每个JsonObject都包含一个"id"键,但其他键值对的数量是不确定的,因此我想创建一个具有2个属性的对象:

class myGenericObject {
  Map<String, Object> attributes;
  String id;
}

所以我希望我的属性映射看起来像这样:

"keyInt" -> 4711
"keyStr" -> "val1"

我找到了这个解决方案

Map<String, Object> attributes = new HashMap<String, Object>();
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
  attributes.put(entry.getKey(), jsonObject.get(entry.getKey()));
}

但是数值被""包围

"keyInt" -> "4711"
"keyStr" -> ""val1""

如何获取纯文本值 (4711"val1")?

输入数据:

{
  "id": 0815, 
  "a": "a string",
  "b": 123.4,
  "c": {
    "a": 1,
    "b": true,
    "c": ["a", "b", "c"]
  }
}
或者
{
  "id": 4711, 
  "x": false,
  "y": "y?",
}

是的,我可以剪切第一个和最后一个字符(“),但这将是一个相当悲哀的解决方案(或者不是吗?) - Floyd
5个回答

13

用空格替换""。

   Map<String, Object> attributes = new HashMap<String, Object>();
   Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
   for(Map.Entry<String,JsonElement> entry : entrySet){
    if (! nonProperties.contains(entry.getKey())) {
      properties.put(entry.getKey(), jsonObject.get(entry.getKey()).replace("\"",""));
    }
   }

只有解决 "val1" 的问题,而不是 "4711" 的问题。 - Floyd
1
请使用'entry.getValue().getAsString()'代替'jsonObject.get(entry.getKey()).replace(""","")'。 - Javad B

4
你是如何创建你的JsonObject的?你的代码对我来说可以工作。考虑这个:
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
...
...
...
try{
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("keyInt", 2);
        jsonObject.addProperty("keyString", "val1");
        jsonObject.addProperty("id", "0123456");

        System.out.println("json >>> "+jsonObject);

        Map<String, Object> attributes = new HashMap<String, Object>();
        Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
        for(Map.Entry<String,JsonElement> entry : entrySet){
          attributes.put(entry.getKey(), jsonObject.get(entry.getKey()));
        }

        for(Map.Entry<String,Object> att : attributes.entrySet()){
            System.out.println("key >>> "+att.getKey());
            System.out.println("val >>> "+att.getValue());
            } 
    }
    catch (Exception ex){
        System.out.println(ex);
    }

它正在良好地运作。现在我想知道你是如何创建那个 JSON 的?

你也可以尝试使用这个(JSONObject)。

import org.json.JSONObject;
...
...
...
try{
        JSONObject jsonObject = new JSONObject("{\"keyInt\":2,\"keyString\":\"val1\",\"id\":\"0123456\"}");
        System.out.println("JSON :: "+jsonObject.toString());

        Iterator<String> it  =  jsonObject.keys();
         while( it.hasNext() ){
             String key = it.next();
             System.out.println("Key:: !!! >>> "+key);
             Object value = jsonObject.get(key);
             System.out.println("Value Type "+value.getClass().getName());
            }
    }
    catch (Exception ex){
        System.out.println(ex);
    }

好的,我不会创建任何JSON,我是从数据库中获取它。 - Floyd
请问您能否将从数据库获取的转储内容粘贴到问题中? - Syed Mauze Rehan

3

只需要进行以下更改...

Map<String, Object> attributes = new HashMap<String, Object>();
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
 attributes.put(entry.getKey(), jsonObject.get(entry.getKey()).getAsString());
}

"getAsString"会为你完成魔法。

2
您的地图值是JsonElement。每当您打印一个JsonElement(例如使用调试器时),它的toString()方法将被调用 - 由于JsonElement具有许多实现类,因此默认的toString实现会在值两侧添加引号以确保正确的JSON格式。要将值作为普通的未加引号的String获取,只需调用getAsString()方法即可:
JsonElement elem;
// ...
String value = elem.getAsString();

使用您的示例:

Map<String, Object> attributes = new HashMap<String, Object>();
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
  attributes.put(entry.getKey(), jsonObject.get(entry.getKey()).getAsString());
}

注意,您可以调用许多其他的方法在 JsonElement 上来生成其他类型。

0

我不太确定你为什么要首先进行手动操作。GSON解码将简单地将那些缺失的键/值对留作默认值(零,null)。然后您可以按照您的意愿进行处理。


我想用只有一个(更或者少通用)类来处理所有传入的json数据(包含一个键为“id”和一个未知数量的键/值对),其中所有键/值对中键不等于“id”的部分都存储在HashMap中。目前我已经成功实现了,但是每个值都被包裹在引号中。 - Floyd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接