我从一个返回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模块。
我已经克服了一个自定义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;
}
这个解决方案的缺点是,我的地图的键总是类型“字符串”。然而,通过改变某些东西,人们可以使它变得通用。此外,我需要说,值的类应该在构造函数中传递。因此,代码中的getMyType()方法返回Map值的类型,该类型被传递到构造函数中。
你可以参考这篇文章我如何为Gson编写一个自定义JSON反序列化?以了解有关自定义反序列化器的更多信息。
我也有同样的问题,结果来了这里。我有一个不同的方法,看起来简单得多(也许是gson的新版本?)
Gson gson = new Gson();
Map jsonObject = (Map) gson.fromJson(data, Object.class);
使用以下json
{
"map-00": {
"array-00": [
"entry-00",
"entry-01"
],
"value": "entry-02"
}
}
以下
Map map00 = (Map) jsonObject.get("map-00");
List array00 = (List) map00.get("array-00");
String value = (String) map00.get("value");
for (int i = 0; i < array00.size(); i++) {
System.out.println("map-00.array-00[" + i + "]= " + array00.get(i));
}
System.out.println("map-00.value = " + value);
输出
map-00.array-00[0]= entry-00
map-00.array-00[1]= entry-01
map-00.value = entry-02
您可以在导航jsonObject时使用instanceof动态检查。类似的
Map json = gson.fromJson(data, Object.class);
if(json.get("field") instanceof Map) {
Map field = (Map)json.get("field");
} else if (json.get("field") instanceof List) {
List field = (List)json.get("field");
} ...
它对我有效,所以它一定对你有效;-)
从gson 2.8.0开始支持以下内容
public static Type getMapType(Class keyType, Class valueType){
return TypeToken.getParameterized(HashMap.class, keyType, valueType).getType();
}
public static <K,V> HashMap<K,V> fromMap(String json, Class<K> keyType, Class<V> valueType){
return gson.fromJson(json, getMapType(keyType,valueType));
}
你可以使用这个类代替:)(处理甚至列表,嵌套列表和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使用:
HashMap<String, Object> hashMap = new HashMap<>(Utility.jsonToMap(response)) ;