Android 改装和GSON以解析没有名称的对象数组

Android 改装和GSON以解析没有名称的对象数组,android,gson,retrofit,retrofit2,Android,Gson,Retrofit,Retrofit2,我得到的JSON响应如下: { "USA": [ "New York", "Texas", "Hawaii" ], "Turkey": [ "Ankara", "Istanbul" ], "Lebanon": [ "Beirut", "Zahle" ] } 我想把这个当作 公共类国家{ 私有字符串名称=null; 私有列表城市=空; }

我得到的JSON响应如下:

{
    "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