在前面我们已经讲解了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解析大概就是这些内容,其实还有好多第三方的解析方式,大家可以探索一下。