在 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}
...
使用自定义反序列化器的解决方案
(NB: 除非你被困在Gson 2.0之前的版本中,否则实际上你不需要自定义反序列化器。但是,了解如何在Gson中进行自定义反序列化(和序列化)仍然很有用,并且根据您要使用解析数据的方式,这通常可能是最佳方法。)
因此,我们确实正在处理随机/变化的字段名称。(当然,这种JSON格式不是很好;这种数据应该在一个 JSON数组中,这样它可以很容易地读入到List中。嗯,我们仍然可以解析这个。)
首先,这是我如何在Java对象中建模JSON数据:
public class City {
String citiesId;
String city;
String regionName;
}
public class CityList {
List<City> cities;
public CityList(List<City> cities) {
this.cities = cities;
}
}
接下来是解析。处理这种JSON的一种方法是为顶层对象(CityList)创建一个自定义反序列化器。
类似于这样:
public class CityListDeserializer implements JsonDeserializer<CityList> {
@Override
public CityList deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = element.getAsJsonObject();
List<City> cities = new ArrayList<City>();
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
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库。