Gson解析JSON數(shù)組

五種方法解析各種情況下的JSON數(shù)組

"muser": [
    {
      "name": "zhangsan",
      "age": "10",
      "phone": "11111",
      "email": "11111@11.com"
    },
    ...
]
  • 這里的 "muser" ,就是數(shù)組的名稱(chēng),稱(chēng)它為數(shù)據(jù)頭,防止跟里面的字段有歧義
  • 如果沒(méi)有數(shù)據(jù)頭,那就叫它純數(shù)據(jù),或者純數(shù)組數(shù)據(jù)
  • 代碼中用到的JsonArray/JsonObject等都來(lái)自GSON
沒(méi)有數(shù)據(jù)頭的純數(shù)組JSON如何解析?

解析的JSON數(shù)組(JsonArray):

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

這種JSON數(shù)組格式,強(qiáng)大的GSON會(huì)直接解析成一個(gè)List。但是這里我們先用原始的方法去解析。

  1. 首先我們需要建立一個(gè)Bean對(duì)象,注意變量名和字段名稱(chēng)一致(不一致時(shí),可以使用序列化):
public class UserBean {
    //變量名跟JSON數(shù)據(jù)的字段名需要一致
    private String name ;
    private String age;
    private String phone;
    private String email;
    ...
}
  1. 解析過(guò)程:
/**
 * 解析沒(méi)有數(shù)據(jù)頭的純數(shù)組
 */
private void parseNoHeaderJArray() {
    //拿到本地JSON 并轉(zhuǎn)成String
    String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_1);

    //Json的解析類(lèi)對(duì)象
    JsonParser parser = new JsonParser();
    //將JSON的String 轉(zhuǎn)成一個(gè)JsonArray對(duì)象
    JsonArray jsonArray = parser.parse(strByJson).getAsJsonArray();

    Gson gson = new Gson();
    ArrayList<UserBean> userBeanList = new ArrayList<>();

    //加強(qiáng)for循環(huán)遍歷JsonArray
    for (JsonElement user : jsonArray) {
        //使用GSON,直接轉(zhuǎn)成Bean對(duì)象
        UserBean userBean = gson.fromJson(user, UserBean.class);
        userBeanList.add(userBean);
    }
    mainLView.setAdapter(new UserAdapter(this, userBeanList));
}

步驟如下:

  • 無(wú)論JSON來(lái)自本地還是網(wǎng)絡(luò)獲取,都要先將JSON轉(zhuǎn)化成String;
  • 需要一個(gè)JSON解析類(lèi)對(duì)象將JSON字符串轉(zhuǎn)換成JsonArray,前提是我們知道JSON 中只有純數(shù)組;
  • 循環(huán)遍歷JsonArray,并用Gson解析成相應(yīng)的對(duì)象
注意:
  1. JsonParse,這是一個(gè)解析類(lèi)它可以把json數(shù)據(jù)分別通過(guò)getAsJsonObject和getAsJsonArray解析成JsonObject和JsonArray.
  2. JsonElement,一個(gè)抽象類(lèi),代表JSON串中的某一個(gè)元素,
有數(shù)據(jù)頭的純數(shù)組數(shù)據(jù)改如何解析?

內(nèi)容和上面的JSON一樣,只不過(guò)是加了一個(gè)名稱(chēng)“muser”,也就是約定好的數(shù)據(jù)頭:

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

解析過(guò)程:

/**
 * 解析有數(shù)據(jù)頭的純數(shù)組
 */
private void parseHaveHeaderJArray() {
    //拿到本地JSON 并轉(zhuǎn)成String
    String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_2);

    //先轉(zhuǎn)JsonObject
    JsonObject jsonObject = new JsonParser().parse(strByJson).getAsJsonObject();
    //再轉(zhuǎn)JsonArray 加上數(shù)據(jù)頭
    JsonArray jsonArray = jsonObject.getAsJsonArray("muser");

    Gson gson = new Gson();
    ArrayList<UserBean> userBeanList = new ArrayList<>();

    //循環(huán)遍歷
    for (JsonElement user : jsonArray) {
        //通過(guò)反射 得到UserBean.class
        UserBean userBean = gson.fromJson(user, new TypeToken<UserBean>() {}.getType());
        userBeanList.add(userBean);
    }
    mainLView.setAdapter(new UserAdapter(this, userBeanList));
}
  1. TypeToken
    它其實(shí)是一個(gè)匿名內(nèi)部類(lèi),官方解釋?zhuān)篏son提供了TypeToken這個(gè)類(lèi)來(lái)幫助我們捕獲像list這樣的泛型信息。java編譯器就會(huì)把捕獲到的泛型信息編譯到這個(gè)匿名內(nèi)部類(lèi)中,然后再運(yùn)行時(shí)就會(huì)被getType()方法用反射的API提取到。其實(shí)就是將T轉(zhuǎn)成.class。
有數(shù)據(jù)頭的復(fù)雜數(shù)據(jù)該如何解析?
{
  "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"
    },
    ...
  ]
}
  • 根據(jù)json建立Bean,注意這里的Bean是返回所有的字段,因?yàn)镚SON能直接解析成list,所以Bean是下面這樣的,
/**
 * Created by xiarui on 2016/8/30.
 * 返回所有結(jié)果的Bean
 */
public class ResultBean {
    //注意變量名與字段名一致
    private int code;
    private String msg;
    private List<UserBean> muser;

    public class UserBean{
        private String name ;
        private String age;
        private String phone;
        private String email;
        ...
    }
    ...
}

注意,這里ResultBean里面有一個(gè)UserBean,雖然和上面兩種的內(nèi)容一樣,但是作用不一樣,這里作為JsonArray解析后存入List中的對(duì)象。

/**
 * 有消息頭 復(fù)雜數(shù)據(jù) 常規(guī)方式
 */
private void parseComplexJArrayByCommon() {
    //拿到Json字符串
    String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_3);
    //GSON直接解析成對(duì)象
    ResultBean resultBean = new Gson().fromJson(strByJson,ResultBean.class);
    //對(duì)象中拿到集合
    List<ResultBean.UserBean> userBeanList = resultBean.getMuser();
    //展示到UI中
    mainLView.setAdapter(new ResultAdapter(this, userBeanList));
}
直接解析復(fù)雜JSON中的數(shù)組或數(shù)組中的某部分內(nèi)容
{
  "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”這個(gè)數(shù)組中的年齡大于30歲該怎么做?

  • 第一點(diǎn)肯定就是剛才提到的遍歷,這個(gè)很好理解,所以我們先要取這一個(gè)數(shù)組(JsonArray),那么如何取呢?還記得之前提到的 JsonParse 么,它的 getAsJsonArray() 可以傳入 數(shù)據(jù)頭 拿到數(shù)組,當(dāng)然不要忘了最外面一層是個(gè) JsonObject 。
  • 拿到數(shù)組以后,我們就可以遍歷了,經(jīng)過(guò)第一二招的洗禮,相信在遍歷上,應(yīng)該沒(méi)什么問(wèn)題了,使用的還是之前提到的 JsonElement 。
    完整代碼:
/**
 * 有數(shù)據(jù)頭 復(fù)雜數(shù)據(jù) 截取方式
 */
private void parseComplexJArrayByDirect() {
    //拿到JSON字符串
    String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_3);
    List<UserBean> userBeanList = new ArrayList<>();

    //拿到數(shù)組
    JsonObject jsonObject = new JsonParser().parse(strByJson).getAsJsonObject();
    JsonArray jsonArray = jsonObject.getAsJsonArray("muser");

    //循環(huán)遍歷數(shù)組
    for (JsonElement user : jsonArray) {
        UserBean userBean = new Gson().fromJson(user, new TypeToken<UserBean>() {
        }.getType());
        //根據(jù)條件過(guò)濾
        if (Integer.parseInt(userBean.getAge()) > 30) {
            userBeanList.add(userBean);
        }
    }
    mainLView.setAdapter(new UserAdapter(this, userBeanList));
}
解析一個(gè)很復(fù)雜的JSON數(shù)據(jù)
{
  "group": {
    "user": {
      "name": "張三",
      "age": "10",
      "phone": "11111",
      "email": "11111@11.com"
    },
    "info": {
      "address": "北京",
      "work": "Android Dev",
      "pay": "10K",
      "motto": "先定一個(gè)小目標(biāo),比如我先賺一個(gè)億"
    }
  }
}

解析過(guò)程

/**
 * 通過(guò)JsonReader的方式去解析
 */
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這個(gè)節(jié)點(diǎn)
            readGroup(reader);
        }
        reader.endObject();
    } finally {
        reader.close();
    }
}

/**
 * 讀group這個(gè)節(jié)點(diǎn)
 *
 * @param reader JsonReader
 */
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();
}

/**
 * 讀用戶基本消息 user節(jié)點(diǎn)
 *
 * @param reader JsonReader
 */
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();
}

/**
 * 讀用戶其他消息 info節(jié)點(diǎn)
 *
 * @param reader JsonReader
 */
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();
}

過(guò)程有省略。。。。
參考:http://blog.csdn.net/qq_35114086/article/details/52705817
https://www.tuicool.com/articles/FrI3uq
http://blog.csdn.net/tkwxty/article/details/34474501/
http://blog.csdn.net/chunqiuwei/article/details/49160321
http://www.myexception.cn/program/1909359.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容