我不确定是否存在开箱即用的东西(谈到 Gson)。但是,您可以编写自定义递归反序列化器:
Type t = new TypeToken<Map<String, String>>(){}.getType();
Gson gson = new GsonBuilder().registerTypeAdapter(t, new FlattenDeserializer()).create();
Map<String, String> map = gson.fromJson(new FileReader(new File("file")), t);
...
class FlattenDeserializer implements JsonDeserializer<Map<String, String>> {
@Override
public Map<String, String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Map<String, String> map = new LinkedHashMap<>();
if (json.isJsonArray()) {
for (JsonElement e : json.getAsJsonArray()) {
map.putAll(deserialize(e, typeOfT, context));
}
} else if (json.isJsonObject()) {
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
if (entry.getValue().isJsonPrimitive()) {
map.put(entry.getKey(), entry.getValue().getAsString());
} else {
map.putAll(deserialize(entry.getValue(), typeOfT, context));
}
}
}
return map;
}
}
根据您的示例,它会输出:
{id="123", name="Tom", subject="Math", teacher="Jack"}
虽然它不能处理将键映射到基元数组的情况(因为无法在 Map<String, String> 中映射具有多个值的键(除非您可以采用数组的字符串表示或你可以返回一个Map<String, Object>),但它适用于一个对象数组(假设每个对象都有一个唯一的键)。
如果你有:
{
"id": "123",
"name": "Tom",
"class": {
"keys": [
{
"key1": "value1"
},
{
"key2": "value2"
}
],
"teacher": "Jack"
}
}
它会输出:
{id="123", name="Tom", key1="value1", key2="value2", teacher="Jack"}
如果需要处理更多案例,您可以根据需要自定义它。
希望对您有所帮助! :)