Android中如何将JSON嵌套字段映射到Java类属性
解决GSON嵌套JSON对象映射到平级Java属性的问题
方法一:定义嵌套结构对应类
GSON默认需要匹配的类结构来解析嵌套JSON,因此可以在Pais类中创建内部类对应name和flags的嵌套结构,通过@SerializedName绑定字段后,可直接通过属性或getter获取目标值:
public class Pais { @SerializedName("name") @Expose private Name name; @SerializedName("region") @Expose private String regiao; @SerializedName("population") @Expose private int populacao; @SerializedName("flags") @Expose private Flags flags; // 获取国家常用名称 public String getNome() { return name != null ? name.common : null; } // 获取国旗PNG地址 public String getBandeira() { return flags != null ? flags.png : null; } // 对应name嵌套结构的内部类 public static class Name { @SerializedName("common") @Expose public String common; } // 对应flags嵌套结构的内部类 public static class Flags { @SerializedName("png") @Expose public String png; } // 按需添加其他getter/setter }
这种方式符合GSON原生解析逻辑,代码结构清晰,易于维护。
方法二:自定义反序列化器手动映射
若要直接将嵌套字段映射到Pais的平级属性,可自定义JsonDeserializer手动解析JSON:
1. 调整Pais为平级结构
public class Pais { private String nome; private String regiao; private int populacao; private String bandeira; // 全参构造器、getter/setter按需实现 }
2. 实现自定义反序列化逻辑
public class PaisDeserializer implements JsonDeserializer<Pais> { @Override public Pais deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObj = json.getAsJsonObject(); Pais pais = new Pais(); // 解析name.common到nome if (jsonObj.has("name")) { JsonObject nameObj = jsonObj.getAsJsonObject("name"); pais.setNome(nameObj.get("common").getAsString()); } // 解析基础字段 pais.setRegiao(jsonObj.get("region").getAsString()); pais.setPopulacao(jsonObj.get("population").getAsInt()); // 解析flags.png到bandeira if (jsonObj.has("flags")) { JsonObject flagsObj = jsonObj.getAsJsonObject("flags"); pais.setBandeira(flagsObj.get("png").getAsString()); } return pais; } }
3. 注册反序列化器到Gson
创建Gson实例时注册自定义解析器:
Gson gson = new GsonBuilder() .registerTypeAdapter(Pais.class, new PaisDeserializer()) .create(); // 后续解析代码保持不变 if (textoJSON != null) { Type type = new TypeToken<ArrayList<Pais>>() {}.getType(); paises = gson.fromJson(textoJSON, type); handler.post(() -> { paisAdapter = new PaisAdapter(this, paises); listView.setAdapter(paisAdapter); }); }
关键注意点
你的请求URL中使用了flag字段参数,但API实际返回的是flags(复数形式),会导致国旗数据解析失败,需修正URL为:https://restcountries.com/v2/all?fields=name,region,population,flags,numericCode
内容的提问来源于stack exchange,提问作者CharlesAnjos
相关产品推荐
相关产品推荐

