五种方法解析各种情况下的JSON数组
"muser": [
{
"name": "zhangsan",
"age": "10",
"phone": "11111",
"email": "[email protected]"
},
...
]
- 这里的 "muser" ,就是数组的名称,称它为数据头,防止跟里面的字段有歧义
- 如果没有数据头,那就叫它纯数据,或者纯数组数据
- 代码中用到的JsonArray/JsonObject等都来自GSON
没有数据头的纯数组JSON如何解析?
解析的JSON数组(JsonArray):
[
{
"name": "zhangsan",
"age": "10",
"phone": "11111",
"email": "[email protected]"
},
{
"name": "lisi",
"age": "20",
"phone": "22222",
"email": "[email protected]"
},
...
]
这种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": "[email protected]"
},
{
"name": "lisi",
"age": "20",
"phone": "22222",
"email": "[email protected]"
},
...
]
}
解析过程:
/**
* 解析有数据头的纯数组
*/
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": "[email protected]"
},
{
"name": "lisi",
"age": "20",
"phone": "22222",
"email": "[email protected]"
},
...
]
}
- 根据json建立Bean,注意这里的Bean是返回所有的字段,因为GSON能直接解析成list,所以Bean是下面这样的,
/**
* Created by xiarui on 2016/8/30.
* 返回所有结果的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": "[email protected]"
},
{
"name": "lisi",
"age": "20",
"phone": "22222",
"email": "[email protected]"
},
...
]
}
假如只想取“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": "[email protected]"
},
"info": {
"address": "北京",
"work": "Android Dev",
"pay": "10K",
"motto": "先定一个小目标,比如我先赚一个亿"
}
}
}
解析过程
/**
* 通过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这个节点
readGroup(reader);
}
reader.endObject();
} finally {
reader.close();
}
}
/**
* 读group这个节点
*
* @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节点
*
* @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节点
*
* @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();
}
过程有省略。。。。
参考: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