Android 改装和GSON以解析没有名称的对象数组
我得到的JSON响应如下:Android 改装和GSON以解析没有名称的对象数组,android,gson,retrofit,retrofit2,Android,Gson,Retrofit,Retrofit2,我得到的JSON响应如下: { "USA": [ "New York", "Texas", "Hawaii" ], "Turkey": [ "Ankara", "Istanbul" ], "Lebanon": [ "Beirut", "Zahle" ] } 我想把这个当作 公共类国家{ 私有字符串名称=null; 私有列表城市=空; }
{
"USA": [
"New York",
"Texas",
"Hawaii"
],
"Turkey": [
"Ankara",
"Istanbul"
],
"Lebanon": [
"Beirut",
"Zahle"
]
}
我想把这个当作
公共类国家{
私有字符串名称=null;
私有列表城市=空;
}
当JSON对象没有类似的名称时,我们如何解析它们
{
"name": "USA",
"cities": [
"New York",
.... etc
}
??提前谢谢。对我来说就像一张地图。尝试将其解析为
Map
。然后您可以分别访问键和值。对我来说就像一张地图。尝试将其解析为Map
。然后您可以分别访问键和值。Gson的默认DTO字段注释用于简单情况。对于更复杂的反序列化,您可能希望使用自定义类型适配器和(反)序列化器,以更为Gson惯用的方式避免映射和列表等弱类型DTO
假设您有以下DTO:
final class国家/地区{
私有最终字符串名;
私人最终名单城市;
国家(最终字符串名称、最终列表城市){
this.name=名称;
这个。城市=城市;
}
字符串getName(){
返回名称;
}
城市列表(){
回归城市;
}
}
假设采用“非标准”JSON布局,以下反序列化程序将递归遍历JSON对象树,以收集国家的目标列表。说
final类countriesJSON反序列化器
实现JsonDeserializer{
私有静态最终JsonDeserializer countryArrayJsonDeserializer=new CountriesJsonDeserializer();
私有静态最终类型listOfStringType=new-TypeToken(){
}.getType();
private CountriesJSON反序列化程序(){
}
静态JsonDeserializer getCountryArrayJsonDeserializer(){
返回countryArrayJsonDeserializer;
}
@凌驾
公共列表反序列化(最终JsonElement json、最终类型类型、最终JsonDeserializationContext)
抛出JsonParseException{
最终列表国家=新的ArrayList();
final JsonObject root=json.getAsJsonObject();
for(最终条目e:root.entrySet()){
最终字符串名称=e.getKey();
最终列表cities=context.deserialize(e.getValue(),listOfStringType);
添加(新国家(名称、城市));
}
返回国;
}
}
上面的反序列化程序将绑定到列表
映射。作为第一步,它将抽象的JsonElement
投射到JsonObject
以遍历其属性(“USA”
,“Turkey”
,以及“leba嫩”
)。假设属性名称本身是国家名称,城市名称列表(属性值)可以委托给序列化上下文,并解析为list
实例(注意类型标记)。解析了name
和cities
后,您可以构建一个Country
实例并收集结果列表
如何使用:
private static final Type listOfCountryType = new TypeToken<List<Country>>() {
}.getType();
private static final Gson gson = new GsonBuilder()
.registerTypeAdapter(listOfCountryType, getCountryArrayJsonDeserializer())
.create();
public static void main(final String... args) {
final List<Country> countries = gson.fromJson(JSON, listOfCountryType);
for ( final Country country : countries ) {
out.print(country.getName());
out.print(" => ");
out.println(country.getCities());
}
}
并使用定制的Gson感知转换器构建一个改装
实例:
//这些static只是从上面的示例中借用的
公共静态void main(最终字符串…参数){
//构建改造实例
最终改装改装=新改装.Builder()
.baseUrl(…您的URL位于此处…)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
//通过改装来代理geo服务
最终的IGeoService geoService=改装.create(IGeoService.class);
//呼叫远程服务
最终调用countriesCall=geoService.getCountries();
countriesCall.enqueue(新回调(){
@凌驾
公共void onResponse(最终呼叫,最终响应){
dumpCountries(“来自远程JSON:,response.body());
}
@凌驾
失败时公共无效(最终调用、最终可丢弃){
抛出新的RuntimeException(throwable);
}
});
//或者只取一个预定义的字符串
dumpCountries(“来自随时可用的JSON:,gson.fromJson(JSON,listOfCountryType));
}
私有静态无效转储国家/地区(最终字符串名称,最终Iterable国家/地区){
out.println(名称);
适用于(最终国家:国家){
out.print(country.getName());
输出。打印(=>);
out.println(country.getCities());
}
out.println();
}
如果由于Country
类及其JSON反序列化程序(我的意思是,您已经有另一个“Country”类用于不同的目的)而导致类型冲突,只需重命名该Country
类,以免影响“正常工作”的映射
输出:
来自随时可用的JSON:美国=>[纽约、德克萨斯、夏威夷]
土耳其=>[安卡拉,伊斯坦布尔]
黎巴嫩=>[贝鲁特,扎勒] 从远程JSON:
美国=>[纽约、德克萨斯、夏威夷]
土耳其=>[安卡拉,伊斯坦布尔]
黎巴嫩=>[贝鲁特,扎勒]
Gson的默认DTO字段注释用于简单情况。对于更复杂的反序列化,您可能希望使用自定义类型适配器和(反)序列化器,以更为Gson惯用的方式避免映射和列表等弱类型DTO 假设您有以下DTO:
final class国家/地区{
私有最终字符串名;
私人最终名单城市;
国家(最终字符串名称、最终列表城市){
this.name=名称;
这个。城市=城市;
}
字符串getName(){
返回名称;
}
城市列表(){
回归城市;
}
}
假设采用“非标准”JSON布局,以下反序列化程序将递归遍历JSON对象树,以收集国家的目标列表。说
final类countriesJSON反序列化器
实现JsonDeserializer{
私有静态最终JsonDeserializer countryArrayJsonDeserial