如何使用Gson解码未知字段的JSON?

我有类似这样的JSON:

{ "unknown_field": { "field1": "str", "field2": "str", "field3": "str", "field4": "str", "field5": "str" }, ...... } 

我创建了一些类来映射这个json

 public class MyModel implements Serializable { private int id; private HashMap models; // getters and setter for id and models here } 

和类Model1是一个只有String字段的简单类。

但它不起作用。

编辑 : JSON格式如下所示:

 { "1145": { "cities_id": "1145", "city": "Nawanshahr", "city_path": "nawanshahr", "region_id": "53", "region_district_id": "381", "country_id": "0", "million": "0", "population": null, "region_name": "Punjab" }, "1148": { "cities_id": "1148", "city": "Nimbahera", "city_path": "nimbahera", "region_id": "54", "region_district_id": "528", "country_id": "0", "million": "0", "population": null, "region_name": "Rajasthan" }, ... } 

(在OP评论说实际上JSON看起来像这样 ,我完全更新了答案。)

Gson 2.0+的解决方案

我刚刚了解到 ,对于较新的Gson版本,这非常简单:

 GsonBuilder builder = new GsonBuilder(); Object o = builder.create().fromJson(json, Object.class); 

创建的对象是Map(com.google.gson.internal.LinkedTreeMap),如果您打印它,它看起来像这样:

 {1145={cities_id=1145, city=Nawanshahr, city_path=nawanshahr, region_id=53, region_district_id=381, country_id=0, million=0, population=null, region_name=Punjab}, 1148={cities_id=1148, city=Nimbahera, city_path=nimbahera, region_id=54, region_district_id=528, country_id=0, million=0, population=null, region_name=Rajasthan} ... 

使用自定义反序列化器的解决方案

注意 :事实certificate你并不是真正的自定义反序列化器,除非你坚持使用2.0版本的Gson。但是知道如何在Gson中进行自定义反序列化(和序列化)仍然很有用,而且它可能经常是最佳方法,取决于您希望如何使用已分析的数据。)

所以我们确实在处理随机/变化的字段名称。 (当然,这种JSON格式不是很好;这种数据应该在JSON数组中 ,在这种情况下,它可以很容易地读入List。哦,我们仍然可以解析它。)

首先,我将如何在Java对象中建模JSON数据:

 // info for individual city public class City { String citiesId; String city; String regionName; // and so on } // top-level object, containing info for lots of cities public class CityList { List cities; public CityList(List cities) { this.cities = cities; } } 

然后,解析。 处理这种JSON的一种方法是为顶级对象(CityList)创建自定义反序列化器

像这样的东西:

 public class CityListDeserializer implements JsonDeserializer { @Override public CityList deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = element.getAsJsonObject(); List cities = new ArrayList(); for (Map.Entry entry : jsonObject.entrySet()) { // For individual City objects, we can use default deserialisation: City city = context.deserialize(entry.getValue(), City.class); cities.add(city); } return new CityList(cities); } } 

需要注意的一个关键点是调用jsonObject.entrySet() ,它返回所有顶级字段(名称如“1145”,“1148”等)。 这个Stack Overflow的答案帮我解决了这个问题。

完整的解析代码如下。 请注意,您需要使用registerTypeAdapter()来注册自定义序列化程序。

 GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(CityList.class, new CityListDeserializer()); Gson gson = builder.setFieldNamingPolicy(LOWER_CASE_WITH_UNDERSCORES).create(); CityList list = gson.fromJson(json, CityList.class); 

(这是我用于测试的完整的可执行示例 。除了Gson之外,它还使用了Guava库。)