Android 不规则 json 格式数据解析

647 阅读4分钟

介绍

数据不是标准的 json 数据,有 key 的都是数字,有些甚至没有key。这种不规则的非键值对数据,不能直接用 Gson 插件生成数据类,只有手动解析之后,自己在重新赋值才能完成!

本示例是安卓项目做的测试例子,只用到 Gson 进行数据解析,使用前需要引入 Gson 依赖包到项目,常规操作,不做展示, 以下解析过程做为交流学习。

数据类

以下为本次需要解析的 json 数据

private static String jsonString = "{\n" +
        "    "code": 2000,\n" +
        "    "detail": "查询成功",\n" +
        "    "data": [\n" +
        "        [\n" +
        "            373,\n" +
        "            2,\n" +
        "            1627978321.591496,\n" +
        "            290.09685230255127,\n" +
        "            [\n" +
        "                2,\n" +
        "                [\n" +
        "                    "一号",\n" +
        "                    "二号"\n" +
        "                ]\n" +
        "            ],\n" +
        "            20,\n" +
        "            [\n" +
        "                [\n" +
        "                    1627978517,\n" +
        "                    14\n" +
        "                ]\n" +
        "            ]\n" +
        "        ]\n" +
        "    ]\n" +
        "}";

封装成对象

因为数据不标准,所以我们不能直接创建一个 bean 类,用 Gson 直接解析,因为 Gson 的直接解析是使用反射的方法來做的。这里我们重新组装的数据类里面的名字要和这个 json 数据里的名字要一样哦。就是对应的数据名字要一样,原因还是因为使用反射的方法來解析嘛。

说完上面这个核心方法,我们可以定义出以下的 bean 类,然后手动地赋值,就可以封装起來了。

主要的 bean 类

这些 bean 结构和 json 里的数据是一样的结构,只是名字不一样。因为 java 中数字不能作为变量的名字,这个我们学 java 就知道啦,标识符的规则。

这个是整体的 bean 类,类参数名称都是随意取地,因为是服务器数据,里面的参数含义都是额外规定的,都是在 log_data_head 这个里面返回来的,每个公司都不同,所以,到时候需要和后台人员约定一下,按照这里面定义参数名字即可,这里只说解析步骤。

public class JsonBean implements Serializable {
   
    private int code;
    private String detail;
    private List<DisListBean> data;
    private List<String> log_data_head;

    @Override
    public String toString() {
        return "JsonBean{" +
                "code=" + code +
                ", detail='" + detail + '\'' +
                ", data=" + data +
                ", log_data_head=" + log_data_head +
                '}';
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    public List<DisListBean> getData() {
        return data;
    }

    public void setData(List<DisListBean> data) {
        this.data = data;
    }

    public List<String> getLog_data_head() {
        return log_data_head;
    }

    public void setLog_data_head(List<String> log_data_head) {
        this.log_data_head = log_data_head;
    }
}

这是 DisListBean 类,对应的字段注释已经标记了

public class DisListBean implements Serializable {
    private int log_id;//id
    private int type;//工作类型
    private float start_time;//工作开始时间
    private float work_time;//工作持续时间
    private int dis_status;//执行结果(状态)
    private DisAreaBean dis_type_areas;//工作范围,消毒区
    private List<DisErrorBean> fault_data;//异常信息

    @Override
    public String toString() {
        return "DisListBean{" +
                "log_id=" + log_id +
                ", type=" + type +
                ", start_time=" + start_time +
                ", work_time=" + work_time +
                ", dis_status=" + dis_status +
                ", dis_type_areas=" + dis_type_areas +
                ", fault_data=" + fault_data +
                '}';
    }

    public int getLog_id() {
        return log_id;
    }

    public void setLog_id(int log_id) {
        this.log_id = log_id;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public float getStart_time() {
        return start_time;
    }

    public void setStart_time(float start_time) {
        this.start_time = start_time;
    }

    public float getWork_time() {
        return work_time;
    }

    public void setWork_time(float work_time) {
        this.work_time = work_time;
    }

    public int getDis_status() {
        return dis_status;
    }

    public void setDis_status(int dis_status) {
        this.dis_status = dis_status;
    }

    public DisAreaBean getDis_type_areas() {
        return dis_type_areas;
    }

    public void setDis_type_areas(DisAreaBean dis_type_areas) {
        this.dis_type_areas = dis_type_areas;
    }

    public List<DisErrorBean> getFault_data() {
        return fault_data;
    }

    public void setFault_data(List<DisErrorBean> fault_data) {
        this.fault_data = fault_data;
    }
}

这是 DisAreaBean 类,对应的字段注释已经标记了

public class DisAreaBean implements Serializable {
    //工作区类型
    private int dis_area_type;
    //工作区名称列表
    private List<String> dis_area_names;

    @Override
    public String toString() {
        return "DisAreaBean{" +
                "dis_area_type=" + dis_area_type +
                ", dis_area_names=" + dis_area_names +
                '}';
    }

    public int getDis_area_type() {
        return dis_area_type;
    }

    public void setDis_area_type(int dis_area_type) {
        this.dis_area_type = dis_area_type;
    }

    public List<String> getDis_area_names() {
        return dis_area_names;
    }

    public void setDis_area_names(List<String> dis_area_names) {
        this.dis_area_names = dis_area_names;
    }
}

这是 DisErrorBean 类,对应的字段注释已经标记了

public class DisErrorBean implements Serializable {

    //工作异常信息
    List<ErrorItem> errorItems;

    @Override
    public String toString() {
        return "DisErrorBean{" +
                "errorItems=" + errorItems +
                '}';
    }

    public List<ErrorItem> getErrorItems() {
        return errorItems;
    }

    public void setErrorItems(List<ErrorItem> errorItems) {
        this.errorItems = errorItems;
    }
}

这是 ErrorItem 类,对应的字段注释已经标记了

public class ErrorItem implements Serializable {

    //[时间戳,异常码]
    private long timestamp;
    private int errorCode;
    
    @Override
    public String toString() {
        return "ErrorItem{" +
                "timestamp=" + timestamp +
                ", errorCode=" + errorCode +
                '}';
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }
}

好了,数据类已经生成好了,接下来就是解析数据,封装进去,对应的字段名称都注释好了,仔细看一遍就知道怎么做了。

数据解析,组装

//整体bean类
JsonBean jsonBean = new JsonBean();
// json解析者
JsonParser jsonParser = new JsonParser();
// 解析成Json对象
JsonObject asJsonObject = jsonParser.parse(jsonString)
    .getAsJsonObject();

int code = asJsonObject.get("code").getAsInt();
jsonBean.setCode(code);

System.out.println("code====" + code);
String details = asJsonObject.get("detail").getAsString();
jsonBean.setDetail(details);
System.out.println("details====" + details);

// log_data_head
JsonArray log_data_head = asJsonObject.get("log_data_head").getAsJsonArray();
System.out.println("log_data_head====" + log_data_head.toString());
List<String> log_data_heads = new ArrayList<>();
for (int array = 0; array < log_data_head.size(); array++) {
    log_data_heads.add(log_data_head.get(array).getAsString());
}
jsonBean.setLog_data_head(log_data_heads);

JsonArray jsonArray1 = asJsonObject.get("data").getAsJsonArray();
System.out.println("jsonArray.get(0)====" + jsonArray1.get(0).toString());

List<DisListBean> bDatas = new ArrayList<>();

for (int i = 0; i < jsonArray1.size(); i++) {
    DisListBean disListBean = new DisListBean();

    JsonArray jsonArray2 = jsonArray1.get(i).getAsJsonArray();
    int log_id = jsonArray2.get(0).getAsInt();
    disListBean.setLog_id(log_id);
    //工作类型
    int type = jsonArray2.get(1).getAsInt();
    disListBean.setType(type);
    //工作开始时间
    float start_time = jsonArray2.get(2).getAsFloat();
    disListBean.setStart_time(start_time);
    //工作持续时间
    float work_time = jsonArray2.get(3).getAsFloat();
    disListBean.setWork_time(work_time);

    //工作范围,工作区
    DisAreaBean disAreaBean = new DisAreaBean();
    JsonArray dis_type_areas = jsonArray2.get(4).getAsJsonArray();
   
    int dis_area_type = dis_type_areas.get(0).getAsInt();
    disAreaBean.setDis_area_type(dis_area_type);
    System.out.println("dis_area_type====" + dis_area_type);
    //工作区名称
    List<String> dis_name = new ArrayList<>();
    JsonArray dis_area_names = dis_type_areas.get(1).getAsJsonArray();
    for (int m = 0; m < dis_area_names.size(); m++) {
        dis_name.add(dis_area_names.get(m).getAsString());
    }
    disAreaBean.setDis_area_names(dis_name);
    System.out.println("dis_area_names====" + dis_area_names.toString());
    disListBean.setDis_type_areas(disAreaBean);

    //工作结果(状态)
    int dis_status = jsonArray2.get(5).getAsInt();
    disListBean.setDis_status(dis_status);

    List<DisErrorBean> fault_Data_List = new ArrayList<>();
    DisErrorBean disErrorBean = new DisErrorBean();
    //工作异常信息
    JsonArray fault_data = jsonArray2.get(6).getAsJsonArray();
    System.out.println("fault_data====" + fault_data.toString());
    for (int f = 0; f < fault_data.size(); f++) {
        // [时间戳,异常码]
        JsonArray fault_data2 = fault_data.get(f).getAsJsonArray();
        System.out.println("fault_data2====" + fault_data2.toString());
        List<ErrorItem> errorItems = new ArrayList<>();
        for (int f2 = 0; f2 < fault_data2.size(); f2++) {
            ErrorItem errorItem = new ErrorItem();
            errorItem.setTimestamp(fault_data2.get(0).getAsLong());
            errorItem.setErrorCode(fault_data2.get(1).getAsInt());
            errorItems.add(errorItem);
        }
        disErrorBean.setErrorItems(errorItems);
    }
    fault_Data_List.add(disErrorBean);
    disListBean.setFault_data(fault_Data_List);
    bDatas.add(disListBean);
}
jsonBean.setData(bDatas);

System.out.println("jsonBean===" + jsonBean.toString());

以上就是整个解析过程,把它弄成一个工具类 ,到时候只需换一下对应的 jsonString 换成网络请求的数据即可。

使用方法

public class GetDataUtils {
    //测试用,正式使用要用网络请求的结果数据
   private static String jsonString = "{\n" +
        "    "code": 2000,\n" +
        "    "detail": "查询成功",\n" +
        "    "data": [\n" +
        "        [\n" +
        "            373,\n" +
        "            2,\n" +
        "            1627978321.591496,\n" +
        "            290.09685230255127,\n" +
        "            [\n" +
        "                2,\n" +
        "                [\n" +
        "                    "一号",\n" +
        "                    "二号"\n" +
        "                ]\n" +
        "            ],\n" +
        "            20,\n" +
        "            [\n" +
        "                [\n" +
        "                    1627978517,\n" +
        "                    14\n" +
        "                ]\n" +
        "            ]\n" +
        "        ]\n" +
        "    ]\n" +
        "}";

    //获取数据
    public static JsonBean getBean(String jsonString) {
        //整体bean类
        JsonBean jsonBean = new JsonBean();
        // json解析者
        JsonParser jsonParser = new JsonParser();
        // 解析成Json对象
        JsonObject asJsonObject = jsonParser.parse(jsonString)
            .getAsJsonObject();

        int code = asJsonObject.get("code").getAsInt();
        jsonBean.setCode(code);

        System.out.println("code====" + code);
        String details = asJsonObject.get("detail").getAsString();
        jsonBean.setDetail(details);
        System.out.println("details====" + details);

        // log_data_head
        JsonArray log_data_head = asJsonObject.get("log_data_head").getAsJsonArray();
        System.out.println("log_data_head====" + log_data_head.toString());
        List<String> log_data_heads = new ArrayList<>();
        for (int array = 0; array < log_data_head.size(); array++) {
            log_data_heads.add(log_data_head.get(array).getAsString());
        }
        jsonBean.setLog_data_head(log_data_heads);

        JsonArray jsonArray1 = asJsonObject.get("data").getAsJsonArray();
        System.out.println("jsonArray.get(0)====" + jsonArray1.get(0).toString());

        List<DisListBean> bDatas = new ArrayList<>();

        for (int i = 0; i < jsonArray1.size(); i++) {
            DisListBean disListBean = new DisListBean();

            JsonArray jsonArray2 = jsonArray1.get(i).getAsJsonArray();
            int log_id = jsonArray2.get(0).getAsInt();
            disListBean.setLog_id(log_id);
            //工作类型
            int type = jsonArray2.get(1).getAsInt();
            disListBean.setType(type);
            //工作开始时间
            float start_time = jsonArray2.get(2).getAsFloat();
            disListBean.setStart_time(start_time);
            //工作持续时间
            float work_time = jsonArray2.get(3).getAsFloat();
            disListBean.setWork_time(work_time);

            //工作范围,工作区
            DisAreaBean disAreaBean = new DisAreaBean();
            JsonArray dis_type_areas = jsonArray2.get(4).getAsJsonArray();
          
            int dis_area_type = dis_type_areas.get(0).getAsInt();
            disAreaBean.setDis_area_type(dis_area_type);
            System.out.println("dis_area_type====" + dis_area_type);
            //工作区名称
            List<String> dis_name = new ArrayList<>();
            JsonArray dis_area_names = dis_type_areas.get(1).getAsJsonArray();
            for (int m = 0; m < dis_area_names.size(); m++) {
                dis_name.add(dis_area_names.get(m).getAsString());
            }
            disAreaBean.setDis_area_names(dis_name);
            System.out.println("dis_area_names====" + dis_area_names.toString());
            disListBean.setDis_type_areas(disAreaBean);

            //工作结果(状态)
            int dis_status = jsonArray2.get(5).getAsInt();
            disListBean.setDis_status(dis_status);

            List<DisErrorBean> fault_Data_List = new ArrayList<>();
            DisErrorBean disErrorBean = new DisErrorBean();
            //工作异常信息
            JsonArray fault_data = jsonArray2.get(6).getAsJsonArray();
            System.out.println("fault_data====" + fault_data.toString());
            for (int f = 0; f < fault_data.size(); f++) {
                // [时间戳,异常码]
                JsonArray fault_data2 = fault_data.get(f).getAsJsonArray();
                System.out.println("fault_data2====" + fault_data2.toString());
                List<ErrorItem> errorItems = new ArrayList<>();
                for (int f2 = 0; f2 < fault_data2.size(); f2++) {
                    ErrorItem errorItem = new ErrorItem();
                    errorItem.setTimestamp(fault_data2.get(0).getAsLong());
                    errorItem.setErrorCode(fault_data2.get(1).getAsInt());
                    errorItems.add(errorItem);
                }
                disErrorBean.setErrorItems(errorItems);
            }
            fault_Data_List.add(disErrorBean);
            disListBean.setFault_data(fault_Data_List);
            bDatas.add(disListBean);
        }
        jsonBean.setData(bDatas);

        System.out.println("jsonBean===" + jsonBean.toString());

        return jsonBean;
    }
}

在对应的 Activity 里面调用,jsonString 换成网络请求结果,bean 就是解析完成的实体类了。

  JsonBean bean = GetDataUtils.getBean(jsonString);

参考文章

blog.csdn.net/zhanqq2012/…

结束

以上就是全部内容了,欢迎大家一起交流学习。