五種方法解析各種情況下的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。但是這里我們先用原始的方法去解析。
- 首先我們需要建立一個(gè)Bean對(duì)象,注意變量名和字段名稱(chēng)一致(不一致時(shí),可以使用序列化):
public class UserBean {
//變量名跟JSON數(shù)據(jù)的字段名需要一致
private String name ;
private String age;
private String phone;
private String email;
...
}
- 解析過(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ì)象
注意:
- JsonParse,這是一個(gè)解析類(lèi)它可以把json數(shù)據(jù)分別通過(guò)getAsJsonObject和getAsJsonArray解析成JsonObject和JsonArray.
- 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));
}
- 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