数组类型不同解析问题探究

我们在开发过程中可以遇到json 数组中的具体的javaBean 不一致现象。例如:

{"list":[{
    "type":a,
    "data":A,
},{
    "type":a,
    "data":B
}]}

如上图所示,list中data的类型根据type的值而变化。像这种bean类型不一致问题,一直烦恼着开发者,现在简单介绍下,几种 可行的解决思路。

方法一:合并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字段根据type而更改

对于数组中data数据结构不同,那么字段就不统一命名成data,而是根据type的不同类型,服务器返回不同的字段,如:person,dog。那么对应的实体类应该是这样的形式:

public class ListBean{
    public String type;
    public PersonBean person;
    public DogBean dog;
}

此方法前提条件就是需要服务器配合,要是你用现成的服务器那么这种方法完全就不用考虑了。
另外这种方法data中类型种类比较多,还会导致ListBean类比较大。而且json中字段不统一。

方法三:Json解析

既然我们的data中的实体类,根据type类型进行改变,我们可以首先解析出来type字段对应的值,然后根据type值得类型,设置data不同的类型的实体类,然后再解析data中数据。
当然关于ListBean中类型统一,可以设置data类型的接口,或者父类,然后子类实现它:
list中data字段对应的基类,

public class DataBean{}

当然你可以将data中子类中相同的字段提取出来,放在DataBean中。
有了DataBean这个虚拟的基类后,我们就可以统一ListBean的类型。
ListBean

public class ListBean{
    public String type;
    public DataBean data;
}

然后让data中具体的不同子类去继承父类DataBean,实现我们需要的子类。

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 我们根据type的类型然后解析data中不同类型的数据。
这个json解析唯一的难点就是必须首先要解析出type的数据,然后根据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());
                    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值