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

我们在开发过程中可以遇到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());
                    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,800评论 19 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,118评论 6 342
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 32,241评论 18 399
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 14,751评论 0 15
  • 芝芝觉得明天的女同胞们可以去浪了,至于男同胞们,就留在办公室加班吧! “每个女人心中都住着一个女王” 女王必备守则...
    牛二宝阅读 2,571评论 0 1