加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Gson解析JSON数组

(2023-06-08 20:17:54)
分类: androidios
 

五种方法解析各种情况下的JSON数组

    "muser": [
        {
          "name": "zhangsan",
          "age": "10",
          "phone": "11111",
          "email": "11111@11.com"
        },
        ...
    ]

    这里的 "muser" ,就是数组的名称,称它为数据头,防止跟里面的字段有歧义
    如果没有数据头,那就叫它纯数据,或者纯数组数据
    代码中用到的JsonArray/JsonObject等都来自GSON

没有数据头的纯数组JSON如何解析?

解析的JSON数组(JsonArray):

    [
      {
        "name": "zhangsan",
        "age": "10",
        "phone": "11111",
        "email": "11111@11.com"
      },
      {
        "name": "lisi",
        "age": "20",
        "phone": "22222",
        "email": "22222@22.com"
      },
      ...
    ]

这种JSON数组格式,强大的GSON会直接解析成一个List。但是这里我们先用原始的方法去解析。

    首先我们需要建立一个Bean对象,注意变量名和字段名称一致(不一致时,可以使用序列化):

    public class UserBean {
        //变量名跟JSON数据的字段名需要一致
        private String name ;
        private String age;
        private String phone;
        private String email;
        ...
    }

    解析过程:

   
    private void parseNoHeaderJArray() {
        //拿到本地JSON 并转成String
        String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_1);
     
        //Json的解析类对象
        JsonParser parser = new JsonParser();
        //将JSON的String 转成一个JsonArray对象
        JsonArray jsonArray = parser.parse(strByJson).getAsJsonArray();
     
        Gson gson = new Gson();
        ArrayList userBeanList = new ArrayList<>();
     
        //加强for循环遍历JsonArray
        for (JsonElement user : jsonArray) {
            //使用GSON,直接转成Bean对象
            UserBean userBean = gson.fromJson(user, UserBean.class);
            userBeanList.add(userBean);
        }
        mainLView.setAdapter(new UserAdapter(this, userBeanList));
    }

步骤如下:

    无论JSON来自本地还是网络获取,都要先将JSON转化成String;
    需要一个JSON解析类对象将JSON字符串转换成JsonArray,前提是我们知道JSON 中只有纯数组;
    循环遍历JsonArray,并用Gson解析成相应的对象

注意:

    JsonParse,这是一个解析类它可以把json数据分别通过getAsJsonObject和getAsJsonArray解析成JsonObject和JsonArray.
    JsonElement,一个抽象类,代表JSON串中的某一个元素,

有数据头的纯数组数据改如何解析?

内容和上面的JSON一样,只不过是加了一个名称“muser”,也就是约定好的数据头:

    {
      "muser": [
        {
          "name": "zhangsan",
          "age": "10",
          "phone": "11111",
          "email": "11111@11.com"
        },
        {
          "name": "lisi",
          "age": "20",
          "phone": "22222",
          "email": "22222@22.com"
        },
        ...
      ]
    }

解析过程:

   
    private void parseHaveHeaderJArray() {
        //拿到本地JSON 并转成String
        String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_2);
     
        //先转JsonObject
        JsonObject jsonObject = new JsonParser().parse(strByJson).getAsJsonObject();
        //再转JsonArray 加上数据头
        JsonArray jsonArray = jsonObject.getAsJsonArray("muser");
     
        Gson gson = new Gson();
        ArrayList userBeanList = new ArrayList<>();
     
        //循环遍历
        for (JsonElement user : jsonArray) {
            //通过反射 得到UserBean.class
            UserBean userBean = gson.fromJson(user, new TypeToken() {}.getType());
            userBeanList.add(userBean);
        }
        mainLView.setAdapter(new UserAdapter(this, userBeanList));
    }

    TypeToken

它其实是一个匿名内部类,官方解释:Gson提供了TypeToken这个类来帮助我们捕获像list这样的泛型信息。java编译器就会把捕获到的泛型信息编译到这个匿名内部类中,然后再运行时就会被getType()方法用反射的API提取到。其实就是将T转成.class。

有数据头的复杂数据该如何解析?

    {
      "code": 200,
      "msg": "OK",
      "muser": [
        {
          "name": "zhangsan",
          "age": "10",
          "phone": "11111",
          "email": "11111@11.com"
        },
        {
          "name": "lisi",
          "age": "20",
          "phone": "22222",
          "email": "22222@22.com"
        },
        ...
      ]
    }

    根据json建立Bean,注意这里的Bean是返回所有的字段,因为GSON能直接解析成list,所以Bean是下面这样的,

   
    public class ResultBean {
        //注意变量名与字段名一致
        private int code;
        private String msg;
        private List muser;
     
        public class UserBean{
            private String name ;
            private String age;
            private String phone;
            private String email;
            ...
        }
        ...
    }

注意,这里ResultBean里面有一个UserBean,虽然和上面两种的内容一样,但是作用不一样,这里作为JsonArray解析后存入List中的对象。

   
    private void parseComplexJArrayByCommon() {
        //拿到Json字符串
        String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_3);
        //GSON直接解析成对象
        ResultBean resultBean = new Gson().fromJson(strByJson,ResultBean.class);
        //对象中拿到集合
        List userBeanList = resultBean.getMuser();
        //展示到UI中
        mainLView.setAdapter(new ResultAdapter(this, userBeanList));
    }

 

直接解析复杂JSON中的数组或数组中的某部分内容

    {
      "code": 200,
      "msg": "OK",
      "muser": [
        {
          "name": "zhangsan",
          "age": "10",
          "phone": "11111",
          "email": "11111@11.com"
        },
        {
          "name": "lisi",
          "age": "20",
          "phone": "22222",
          "email": "22222@22.com"
        },
        ...
      ]
    }

假如只想取“muser”这个数组中的年龄大于30岁该怎么做?

    第一点肯定就是刚才提到的遍历,这个很好理解,所以我们先要取这一个数组(JsonArray),那么如何取呢?还记得之前提到的 JsonParse 么,它的 getAsJsonArray() 可以传入 数据头 拿到数组,当然不要忘了最外面一层是个 JsonObject 。
    拿到数组以后,我们就可以遍历了,经过第一二招的洗礼,相信在遍历上,应该没什么问题了,使用的还是之前提到的 JsonElement 。

完整代码:

   
    private void parseComplexJArrayByDirect() {
        //拿到JSON字符串
        String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_3);
        List userBeanList = new ArrayList<>();
     
        //拿到数组
        JsonObject jsonObject = new JsonParser().parse(strByJson).getAsJsonObject();
        JsonArray jsonArray = jsonObject.getAsJsonArray("muser");
     
        //循环遍历数组
        for (JsonElement user : jsonArray) {
            UserBean userBean = new Gson().fromJson(user, new TypeToken() {
            }.getType());
            //根据条件过滤
            if (Integer.parseInt(userBean.getAge()) > 30) {
                userBeanList.add(userBean);
            }
        }
        mainLView.setAdapter(new UserAdapter(this, userBeanList));
    }

 

解析一个很复杂的JSON数据

    {
      "group": {
        "user": {
          "name": "张三",
          "age": "10",
          "phone": "11111",
          "email": "11111@11.com"
        },
        "info": {
          "address": "北京",
          "work": "Android Dev",
          "pay": "10K",
          "motto": "先定一个小目标,比如我先赚一个亿"
        }
      }
    }

解析过程

   
    private void parseComplexJArrayByReader() throws IOException {
        String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_4);
        JsonReader reader = new JsonReader(new StringReader(strByJson));
        try {
            reader.beginObject();
            String tagName = reader.nextName();
            if (tagName.equals("group")) {
                //读group这个节点
                readGroup(reader);
            }
            reader.endObject();
        } finally {
            reader.close();
        }
    }
     
   
    private void readGroup(JsonReader reader) throws IOException {
        reader.beginObject();
        while (reader.hasNext()) {
            String tagName = reader.nextName();
            if (tagName.equals("user")) {
                readUser(reader);
            } else if (tagName.equals("info")) {
                readInfo(reader);
            }
        }
        reader.endObject();
    }
     
   
    private void readUser(JsonReader reader) throws IOException {
        reader.beginObject();
        while (reader.hasNext()) {
            String tag = reader.nextName();
            if (tag.equals("name")) {
                String name = reader.nextString();
                nameText.setText(name);
            } else if (tag.equals("age")) {
                String age = reader.nextString();
                ageText.setText(age);
            }
            ...
            else {
                reader.skipValue();//忽略
            }
        }
        reader.endObject();
    }
     
   
    private void readInfo(JsonReader reader) throws IOException {
        reader.beginObject();
        while (reader.hasNext()) {
            String tag = reader.nextName();
            if (tag.equals("address")) {
                String address = reader.nextString();
                addressText.setText(address);
            } else if (tag.equals("work")) {
                String work = reader.nextString();
                workText.setText(work);
            }
            ...
            else {
                reader.skipValue();//忽略
            }
        }
        reader.endObject();
    }


 
————————————————
版权声明:本文为CSDN博主「加菲猫的小窝」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wvqusrtg/article/details/108233726

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有