我自己一直在寻找嵌套Map问题的解决方案,上面的“이종은”是第一个真正帮助非平凡用例的答案。
由于上面的解决方案仅处理了 Number I 更新了解决方案,以便为字符串和布尔值提供通用解析功能,请参阅下面的更新代码:
private static class MapDeserializer implements JsonDeserializer<Map<String, Object>> {
public Map<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Map<String, Object> m = new LinkedHashMap<String, Object>();
JsonObject jo = json.getAsJsonObject();
for (Entry<String, JsonElement> mx : jo.entrySet()) {
String key = mx.getKey();
JsonElement v = mx.getValue();
if (v.isJsonArray()) {
m.put(key, g.fromJson(v, List.class));
} else if (v.isJsonPrimitive()) {
Number num = null;
ParsePosition position=new ParsePosition(0);
String vString=v.getAsString();
try {
num = NumberFormat.getInstance(Locale.ROOT).parse(vString,position);
} catch (Exception e) {
}
//Check if the position corresponds to the length of the string
if(position.getErrorIndex() < 0 && vString.length() == position.getIndex()) {
if (num != null) {
m.put(key, num);
continue;
}
}
JsonPrimitive prim = v.getAsJsonPrimitive();
if (prim.isBoolean()) {
m.put(key, prim.getAsBoolean());
} else if (prim.isString()) {
m.put(key, prim.getAsString());
} else {
m.put(key, null);
}
} else if (v.isJsonObject()) {
m.put(key, g.fromJson(v, Map.class));
}
}
return m;
}
}
private static class ListDeserializer implements JsonDeserializer<List<Object>> {
public List<Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
List<Object> m = new ArrayList<Object>();
JsonArray arr = json.getAsJsonArray();
for (JsonElement jsonElement : arr) {
if (jsonElement.isJsonObject()) {
m.add(g.fromJson(jsonElement, Map.class));
} else if (jsonElement.isJsonArray()) {
m.add(g.fromJson(jsonElement, List.class));
} else if (jsonElement.isJsonPrimitive()) {
Number num = null;
try {
num = NumberFormat.getInstance().parse(jsonElement.getAsString());
} catch (Exception e) {
}
if (num != null) {
m.add(num);
continue;
}
JsonPrimitive prim = jsonElement.getAsJsonPrimitive();
if (prim.isBoolean()) {
m.add(prim.getAsBoolean());
} else if (prim.isString()) {
m.add(prim.getAsString());
} else {
m.add(null);
}
}
}
return m;
}
}
private static Gson g = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserializer()).registerTypeAdapter(List.class, new ListDeserializer()).setDateFormat("yyyy-MM-dd HH:mm:ss").create();