Android中Json的全解析(JSONObject,JSONArray,Gson,Jackson)

时间:2021-07-14 18:01:08

在前面我们已经讲解了XML的解析,今天来讲一下Json的解析过程。前面已经对XML和Json进行了详细的对比,这里就不在重述了。

先跟大家描述以下Json的数据结构,有以下两种形式:

1)“名称/值”对的集合

这种“名称/值”对的集合形式又称为JSONObject,其名称和值之间使用“:”隔开,一般的形式如下:{name:value}

例如:{"width":"800","height":800}

其中名称是字符串,值可以是字符串。数值,对象,布尔值,有序列表或者是null值。

2)值的有序列表

值的有序列表形式又称为JSONArray,如下:

[collection,collection]

例如:

{


"employees":[

{"width":"800","height":800},

{"width":"700","height":700},

{"width":"600","height":600}

]

}

就像上面的示例一样,这两种形式可以随意嵌套,实现复杂的Json结构。

我们今天不只是使用系统自带的JsonAPI 来对Json数据进行解析,我们还会使用两种Json解析框架对Json进行解析,它们分别是Gson和Jackson。相信大家对它们都有所耳闻吧。好了,现在我们对它们进行一一的说明。




一、JSONObject、JSONArray解析Json数据

Json数据示例:

{

"Strings":{"Strings1":"MyStrings","Strings2":"MyStrings"},

"Number":["11111","22222","333333","44444"],

"String":"good",

"Int":100,

"Boolean":false

}


因为重点不是使用此种方法解析,所以我们只是简单的把所解析的内容打印出来,并没有存入Bean中。

代码如下:

public void json2String(String jsonString) {

try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONObject Strings = jsonObject.getJSONObject("Strings");
String Strings1 = Strings.getString("Strings1");
String Strings2 = Strings.getString("Strings2");
JSONArray array = jsonObject.getJSONArray("Number");
for (int i = 0; i < array.length(); i++) {
System.out.println(array.getInt(i));
}
String string = jsonObject.getString("String");
int int1 = jsonObject.getInt("Int");
Boolean bool = jsonObject.getBoolean("Boolean");
} catch (JSONException e) {
e.printStackTrace();
}

}

相信大家不难看懂这些代码,稍加练习便可以熟练的使用这种方法解析Json数据,但是如果Json数据非常庞大并且结构复杂的话,再使用这种方法解析就显得力不从心了,下面就给大家介绍两种简单的Json解析方法。

二、Gson解析Json数据

Gson是谷歌的一个开源库,解析方式是基于事件驱动的,根据所需要取的数据通过建立一个相对于Json数据的JavaBean类,然后在通过简单的操作就可以解析出所需的Json数据。不知大家有没有注意到,我上一句说的是根据所需要取的数据,这就说明使用Gson,我们可以实现只取我们需要的Json数据而不用全部取出,当然这样的劣势就是执行效率相对比较低下,那有没有执行效率更快的框架呢,有,我们一会再说。

首先是导入Gson的开源库(这个是gson2.3.1的地址,如点击无效可直接访问http://pan.baidu.com/s/1i5hoZEP)。

接下来就给大家展示如何将JSON数据转换成我们需要的Android对象。

首先我们要定义一个JSON数据对应的POJO,即JavaBeans.Java。那么有些人可能不太熟悉JavaBeans的构建,不用担心,只要按以下两个原则,即可轻松构建:

1、[ ]前面的元素定义成List< B > b形式,如,public List< Face > face;而{ }前面的元素定义为 public C c形式即可,如,public String img_id 或 public Attribute attribute。
2、类里面的属性名必须跟JSON字段里面的Key是一模一样的;

1)先来一个简单的Json的数据。


示例:

{

"id":1,

"name":"JSON",

"sex":"男",

"age":20

}

按照上面的原则,我们先创建一个JavaBeans类,代码如下:

public class Student {
  //确保属性和key的名称一致
private int id;
private String name;
private String sex;
private int age;


public int getId() {
return id;
}

public int getAge() {
return age;
}

public String getName() {
return name;
}

public String getSex() {
return sex;
}

public void setId(int id) {
this.id = id;
}

public void setAge(int age) {
this.age = age;
}

public void setName(String name) {
this.name = name;
}

public void setSex(String sex) {
this.sex = sex;
}

@Override
public String toString() {
String s = "id=" + id + ",name=" + name + ",sex=" + sex + ",age=" + age;
return s;
}
}

然后我们使用Gson转换的代码:


Gson gson=new Gson();
Student student=new Student();
String json="{\"id\":1,\"name\":\"JSON\",\"sex\":\"\",\"age\":20}";
student=gson.fromJson(json,Student.class);
System.out.println(student.toString());

2)下面来看以下在复杂的JSON结构下,Gson如何解析

示例:


{"translation":[""],
"basic":
{
"phonetic":"kɑː",
"explains":["n. 汽车;车厢","n. (Car)人名;()贾尔;(法、西)卡尔;()察尔"]},
"query":"car",
"errorCode":0,
"web":[{"value":["汽车","车子","小汽车"],"key":"Car"},
{"value":["概念车","概念车","概念汽车"],"key":"concept car"},
{"value":["碰碰车","碰撞用汽车","碰碰汽车"],"key":"bumper car"}]
}


同样按照上面的原则,我们还需要创建一个JavaBeans类,代码如下:

public class Translations {
public String[] translation;
public basic basic;

public static class basic {
public String phonetic;
public String[] explains;
}

public String query;
public int errorCode;
public List<wb> web;

public static class wb {
public String[] value;
public String key;
}


public void show() {
//输出数组
for (int i = 0; i < translation.length; i++) {
System.out.println(translation[i]);
}
//输出内部类对象
System.out.println(basic.phonetic);
//输出内部类数组
for (int i = 0; i < basic.explains.length; i++) {
System.out.println(basic.explains[i]);
}
System.out.println(query);
System.out.println(errorCode);
for (int i = 0; i < web.size(); i++) {
for (int j = 0; j < web.get(i).value.length; j++) {
System.out.println(web.get(i).value[j]);
}
System.out.println(web.get(i).key);
}
}
}
好了,我们的实体类就算是写完了,相信大家应该也是废了一番苦功夫吧,如果Json数据再复杂一些那怎么办,给大家推荐一个 Json转实体类的工具,还是比较实用的。
Gson的解析方式跟上面简单的解析方式相同,

JavaBean对象=gson.fromJson(son,javaBean类类名);

大家可以看到,利用Gson解析Json数据的关键是需要写出一个和Json数据结构相对应的JavaBeans实体类,剩下的解析过程就非常简单了。


三、Jackson解析Json数据

Jackson与Gson相同,都是基于事件驱动的,解析方式也相同,也是先创建一个对应于Json数据的JavaBeans实体类,然后通过简单的操作就可以解析出Json数据。但它和Gson还是不同的,我们上面已经提到过Gson可以按照需要进行解析,即创建的JavaBean类不一定涵盖所有的Json数据,可以按需创建实体类的属性。但是Jackson必须解析出所有的Json数据,这就意味着使用Jackson解析时创建的JavaBeans类必须涵盖所有的Json数据,无法按需分配。这时候大家就会疑问了,为什么我有Gson这种更加完善的解析方式,为什么还要有Jackson呢,大家还记得有一招从天而降的掌法吗,哈哈,开个玩笑,大家还记得在上面提到的一个比Gson解析速度更快的框架吗,没错,就是Jackson,它再较大的Json的文件的处理上,简直把Gson遥遥的落在后面。可是为什么会快这么多呢,不是说都是基于事件驱动吗,我也没有详细研究,个人认为应该是使用了流处理方式吧。Jackson需要的类库,点击下载


1)首先要说的还是创建一个与Json数据对应的JavaBeans实体类,因为它创建实体类的规则与Gson一样,我们就不进行详解了。


2)那么接下来我们来看一下如何使用Jackson来解析Json数据。

ObjectMapper mapper = new ObjectMapper();
File json = new File("country.json");
//json映射到java对象
Student student = mapper.readValue(json, Country.class);
大家看一看是不是也很简单。好了,我们的Json解析大概就是这些内容,其实还有好多第三方的解析方式,大家可以探索一下。