【问题标题】:How to iterate a JsonObject (gson)如何迭代 JsonObject (gson)
【发布时间】:2015-03-13 21:49:08
【问题描述】:

我有一个 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?",
}

【问题讨论】:

  • 是的,我可以剪掉第一个和最后一个字符 ("),但这将是一个可悲的解决方案(或者不是?)

标签: java json gson json-deserialization


【解决方案1】:

将“”替换为空白。

   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”的问题
  • 使用 'entry.getValue().getAsString()' intsead 'jsonObject.get(entry.getKey()).replace("\"","")';
【解决方案2】:

你是如何创建你的 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,我从数据库中获取它。
  • 你能粘贴你从数据库中得到的转储(到问题)吗?
【解决方案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" 会为你施展魔法

【讨论】:

    【解决方案4】:

    您的地图值为JsonElements。每当您打印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 调用许多其他方法来生成其他类型。

    【讨论】:

      【解决方案5】:

      我不太清楚你为什么要首先进行手动操作。 GSON 解码只会将那些缺少的键/值对保留为默认值(零,空)。然后您可以根据需要进行处理。

      【讨论】:

      • 我想用一个(或多或少通用)类来处理所有传入的 json(带有一个键“id”和额外未知数量的键/值对),其中所有键/值对其中 key != "id" 存储在 HashMap 中。 Atm 我设法做到了,但每个值都包含在 ".
      猜你喜欢
      • 2021-11-15
      • 2012-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 2016-03-16
      • 2016-10-29
      • 1970-01-01
      相关资源
      最近更新 更多