在前面我们已经讲解了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 {好了,我们的实体类就算是写完了,相信大家应该也是废了一番苦功夫吧,如果Json数据再复杂一些那怎么办,给大家推荐一个 Json转实体类的工具,还是比较实用的。
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);
}
}
}
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();大家看一看是不是也很简单。好了,我们的Json解析大概就是这些内容,其实还有好多第三方的解析方式,大家可以探索一下。
File json = new File("country.json");
//从json映射到java对象
Student student = mapper.readValue(json, Country.class);