我們在開發(fā)過程中可以遇到json 數(shù)組中的具體的javaBean 不一致現(xiàn)象。例如:
{"list":[{
"type":a,
"data":A,
},{
"type":a,
"data":B
}]}
如上圖所示懂诗,list中data的類型根據(jù)type的值而變化蜂嗽。像這種bean類型不一致問題,一直煩惱著開發(fā)者,現(xiàn)在簡單介紹下殃恒,幾種 可行的解決思路植旧。
方法一:合并Bean
如果A與B中的字段不復雜,可以將A离唐,B合并組合成一個比較大的Bean實例病附,他包括A和B中所有的字段。
例如:
{"list":[{
"type":"person",
"data":{
name:"小王",
age:15,
gender:"male"
},
},{
"type":"dog",
"data":{
name:"旺財",
age:2,
species:"家狗"
},
}]}
合并之后的bean 為:
public class combineBean {
public String name;
public int age;
public String gender;
public String species;
}
方法二:data字段根據(jù)type而更改
對于數(shù)組中data數(shù)據(jù)結構不同亥鬓,那么字段就不統(tǒng)一命名成data完沪,而是根據(jù)type的不同類型,服務器返回不同的字段,如:person覆积,dog听皿。那么對應的實體類應該是這樣的形式:
public class ListBean{
public String type;
public PersonBean person;
public DogBean dog;
}
此方法前提條件就是需要服務器配合,要是你用現(xiàn)成的服務器那么這種方法完全就不用考慮了宽档。
另外這種方法data中類型種類比較多尉姨,還會導致ListBean類比較大。而且json中字段不統(tǒng)一吗冤。
方法三:Json解析
既然我們的data中的實體類又厉,根據(jù)type類型進行改變,我們可以首先解析出來type字段對應的值欣孤,然后根據(jù)type值得類型馋没,設置data不同的類型的實體類,然后再解析data中數(shù)據(jù)降传。
當然關于ListBean中類型統(tǒng)一,可以設置data類型的接口勾怒,或者父類婆排,然后子類實現(xiàn)它:
list中data字段對應的基類,
public class DataBean{}
當然你可以將data中子類中相同的字段提取出來笔链,放在DataBean中段只。
有了DataBean這個虛擬的基類后,我們就可以統(tǒng)一ListBean的類型鉴扫。
ListBean
public class ListBean{
public String type;
public DataBean data;
}
然后讓data中具體的不同子類去繼承父類DataBean赞枕,實現(xiàn)我們需要的子類。
public class PersonBean extend DataBean{
public String name;
public int age;
public String gender;
}
public class DogBean extend DataBean{
public String name;
public int age;
public String species ;
}
我們可以安裝Json的解析的方法坪创,首先將返回的json字符串慢慢解析成實體類炕婶,首先解析list,然后里面的type 我們根據(jù)type的類型然后解析data中不同類型的數(shù)據(jù)莱预。
這個json解析唯一的難點就是必須首先要解析出type的數(shù)據(jù)柠掂,然后根據(jù)type才能確定data的不同的實體類型。
其實Gson中可以自定義解析器依沮;
public class ListBeanDeserializer implements JsonDeserializer<TypeResult> {
@Override
public ListBean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (!json.isJsonObject()) {
return null;
}
JsonObject obj = json.getAsJsonObject();
JsonArray asJsonArray = obj.get("list").getAsJsonArray();
ListBean list = new ListBean();
for (JsonElement jsonElement : asJsonArray) {
JsonObject jsonOb = jsonElement.getAsJsonObject();
String type = jsonOb.get("type").getAsString();
if (TextUtils.equal(type,"person")) {
JsonObject child = jsonOb.get("data").getAsJsonObject();
String name = child.get("name").getAsString();
int age = child.get("age").getAsInt();
String gender = child.get("gender").getAsString();
list.data=new Person(name, age,gender);
} else if(TextUtils.equal(type,"dog")) {
JsonObject child = jsonOb.get("data").getAsJsonObject();
String name = child.get("name").getAsString();
int age = child.get("age").getAsInt();
String species = child.get("species").getAsString();
list.data=new Person(name, age,species);
}
}
return list;
}
}
使用解析器解析:
protected ArrayList<ListBean> deserializerResponse(@NonNull Response response) throws IOException {
String json = null;
if (response != null && response.body() != null) {
json = response.body().string();
}
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(ListBean.class, new ListBeanDeserializer());
Gson gson = gsonBuilder.create();
return gson.fromJson(TextUtils.isEmpty(json) ? json : json.trim(), new TypeToken<ArrayList<ListBean>>() {
}.getType());
}