如何使用Gson将JSON转换为HashMap?

319

我正在向服务器请求数据,服务器以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 模块。


31
Map<String,Object> result = new Gson().fromJson(json, Map.class); 可以在 gson 2.6.2 版本中使用。意思是将传入的 json 字符串转化成一个键值对集合(key为String类型,value为Object类型)并存储在result变量中。 - Ferran Maylinch
16个回答

1
您可以使用这个类代替 :) (甚至处理列表、嵌套列表和json)
public class Utility {

    public static Map<String, Object> jsonToMap(Object json) throws JSONException {

        if(json instanceof JSONObject)
            return _jsonToMap_((JSONObject)json) ;

        else if (json instanceof String)
        {
            JSONObject jsonObject = new JSONObject((String)json) ;
            return _jsonToMap_(jsonObject) ;
        }
        return null ;
    }


   private static Map<String, Object> _jsonToMap_(JSONObject json) throws JSONException {
        Map<String, Object> retMap = new HashMap<String, Object>();

        if(json != JSONObject.NULL) {
            retMap = toMap(json);
        }
        return retMap;
    }


    private static Map<String, Object> toMap(JSONObject object) throws JSONException {
        Map<String, Object> map = new HashMap<String, Object>();

        Iterator<String> keysItr = object.keys();
        while(keysItr.hasNext()) {
            String key = keysItr.next();
            Object value = object.get(key);

            if(value instanceof JSONArray) {
                value = toList((JSONArray) value);
            }

            else if(value instanceof JSONObject) {
                value = toMap((JSONObject) value);
            }
            map.put(key, value);
        }
        return map;
    }


    public static List<Object> toList(JSONArray array) throws JSONException {
        List<Object> list = new ArrayList<Object>();
        for(int i = 0; i < array.length(); i++) {
            Object value = array.get(i);
            if(value instanceof JSONArray) {
                value = toList((JSONArray) value);
            }

            else if(value instanceof JSONObject) {
                value = toMap((JSONObject) value);
            }
            list.add(value);
        }
        return list;
    }
}

将您的JSON字符串转换为哈希映射,请使用以下代码:

HashMap<String, Object> hashMap = new HashMap<>(Utility.jsonToMap(response)) ;

1
我已经通过自定义JsonDeSerializer解决了类似的问题。我试图使它更加通用,但还不够。尽管如此,这是一个符合我的需求的解决方案。
首先,您需要为Map对象实现一个新的JsonDeserializer。
public class MapDeserializer<T, U> implements JsonDeserializer<Map<T, U>>

反序列化方法将类似于以下内容:

public Map<T, U> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {

        if (!json.isJsonObject()) {
            return null;
        }

        JsonObject jsonObject = json.getAsJsonObject();
        Set<Entry<String, JsonElement>> jsonEntrySet = jsonObject.entrySet();
        Map<T, U> deserializedMap = new HashMap<T, U>();

        for (Entry<java.lang.String, JsonElement> entry : jsonEntrySet) {
            try {
                U value = context.deserialize(entry.getValue(), getMyType());
                deserializedMap.put((T) entry.getKey(), value);
            } catch (Exception ex) {
                logger.info("Could not deserialize map.", ex);
            }
        }

        return deserializedMap;
    }

这种解决方案的缺点是,我的Map的键始终是“String”类型。但是通过更改一些内容,可以使其成为通用解决方案。此外,需要指出的是,值的类应在构造函数中传递。因此,我的代码中的getMyType()方法返回了在构造函数中传递的Map值的类型。
您可以参考此帖子如何为Gson编写自定义JSON反序列化程序?以了解有关自定义反序列化程序的更多信息。

0

这更像是对Kevin Dolan's answer的补充,而不是完整的答案,但我在从数字中提取类型方面遇到了麻烦。这是我的解决方案:

private Object handlePrimitive(JsonPrimitive json) {
  if(json.isBoolean()) {
    return json.getAsBoolean();
  } else if(json.isString())
    return json.getAsString();
  }

  Number num = element.getAsNumber();

  if(num instanceof Integer){
    map.put(fieldName, num.intValue());
  } else if(num instanceof Long){
    map.put(fieldName, num.longValue());
  } else if(num instanceof Float){
    map.put(fieldName, num.floatValue());
  } else {    // Double
     map.put(fieldName, num.doubleValue());
  }
}

-1
 HashMap<String, String> jsonToMap(String JsonDetectionString) throws JSONException {

    HashMap<String, String> map = new HashMap<String, String>();
    Gson gson = new Gson();

    map = (HashMap<String, String>) gson.fromJson(JsonDetectionString, map.getClass());

    return map;

}

-3

我使用了这段代码:

Gson gson = new Gson();
HashMap<String, Object> fields = gson.fromJson(json, HashMap.class);

这会给我未经检查的转换警告。 - Line

-3

JSONObject通常在内部使用HashMap来存储数据。因此,您可以在代码中将其用作Map。

例如:

JSONObject obj = JSONObject.fromObject(strRepresentation);
Iterator i = obj.entrySet().iterator();
while (i.hasNext()) {
   Map.Entry e = (Map.Entry)i.next();
   System.out.println("Key: " + e.getKey());
   System.out.println("Value: " + e.getValue());
}

12
这是来自json-lib,而不是gson! - Ammar

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