1. Json入门
① 定义
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。具有良好的可读和便于快速编写的特性。
业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。
JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为– Json.org
1. http://shazhuzhu1.iteye.com/blog/974758
2. http://blog.csdn.net/onlyonecoder/article/details/8490924
② Json的语法规则
-
-
数据在键值对中
-
数据由逗号分隔
-
花括号保存对象
-
方括号保存数组
-
1. 表示名称/值对
{ "firstName": "Brett" }
这个示例非常基本,而且实际上比等效的纯文本 "名称 / 值对" 占用更多的空间:firstName=Brett
但是,当将多个"名称 / 值对"串在一起时,JSON 就会体现出它的价值了。首先,可以创建包含多个"名称 / 值对"的 记录,比如:
{ "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" }
从语法方面来看,这与"名称 / 值对"相比并没有很大的优势,但是在这种情况下 JSON 更容易使用,而且可读性更好。例如,它明确地表示以上三个值都是同一记录的一部分;花括号使这些值有了某种联系。
2. 表示数组
假设您希望表示一个人名列表,在 XML 中,需要许多开始标记和结束标记;如果使用典型的 名称 / 值 对,那么必须建立一种专有的数据格式,或
者将键名称修改为 person-数组 这样的形式。
如果使用 JSON,就只需将多个带花括号的记录分组在一起,用方括号围绕表示数组:
{ "people": [
{ "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" },
{ "firstName": "Jason", "lastName":"Hunter", "email": "bbbb"},
{ "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" }
]}
3. Json的基础结构
通过上面的演示,可以清楚的看到Json有两种基础结构
1. “名称/值”对的集合(A collection of name/value pairs),通常将它称作对象
例如:{ "firstName": "Brett" } 表示一个对象
2. 值的有序列表(An ordered list of values),通常将它称作数组
例如:上面person键对应的值是三个人的信息,用方括号围绕
③ xml VS Json
1.JSON和XML的数据可读性基本相同
2.JSON和XML同样拥有丰富的解析手段
3.JSON相对于XML来讲,数据的体积小
4.JSON与JavaScript的交互更加方便
5.JSON对数据的描述性比XML较差
6.JSON的速度要远远快于XML
2. Json数据的解析
① 相关类与API
android2.3提供的json解析类
android的json解析部分都在包org.json下,主要有以下几个类:
1. JSONObject:对象
可以看作是一个json对象,这是系统中有关JSON定义的基本单元,其包含一对儿(Key/Value)数值。
构造方法: JSONObject obj = new JSONObject(String entity);
JSONObject obj = new JSONObject(Map entity);等
主要方法:① JSONObject.toString
调用的响应体现为一个标准的字符串(例如:{"JSON": "Hello, World"},最外被大括号包裹,其中的Key和Value被冒号":"分隔)。
② JSONObject().put(String, value)
在Key和Value之间是以逗号","分隔。Value的类型包括:Boolean、JSONArray、JSONObject、Number、String或者默认值JSONObject.NULL object 。
③ JSONObject.get(String) 和 opt(String)
根据名称得到值,opt(): 这个方法相对比较灵活,当无法获取所指定数值时,将会返回一个默认数值,并不会抛出异常。
2. JSONArray: 数组
它代表一组有序的数值。将其转换为String输出(toString)所表现的形式是用方括号包裹,数值以逗号”,”分隔(例如[value1,value2,value3],大家可以亲自利用简短的代码更加直观的了解其格式)。
主要方法:
① JSONArray.toString()
输出(toString)所表现的形式是用方括号包裹,数值以逗号”,”分隔(例如[value1,value2,value3]
② JSONArray.get(int index) 与 JSONArray.opt(int index) getString(int index), getDouble(index) 等
get()和opt()两种方法都可以通过index索引返回指定的数值
③ JSONArray.put(int index,value)
put()方法用来添加或者替换数值。同样这个类的value类型可以包括:Boolean、JSONArray、JSONObject、Number、String或者默认值JSONObject.NULL object。
3. JSONStringer
json文本构建类 ,根据官方的解释,这个类可以帮助快速和便捷的创建JSON text。
其最大的优点在于可以减少由于 格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则(syntax rules)创建JSON text。
其中的.object()和.endObject()必须同时使用,是为了按照Object标准给数值添加边界。同样,针对数组也有一组标准的方法来生成边界.array()和.endArray()。
下面的例子会讲解
4. JSONTokener:json解析类
实例:从一个map中得到JsonObject
public static JSONObject getJSON(Map map) {
Iterator iter = map.entrySet().iterator();
JSONObject holder = new JSONObject();
while (iter.hasNext()) {
Map.Entry pairs = (Map.Entry) iter.next();
String key = (String) pairs.getKey();
Map m = (Map) pairs.getValue();
JSONObject data = new JSONObject();
try {
Iterator iter2 = m.entrySet().iterator();
while (iter2.hasNext()) {
Map.Entry pairs2 = (Map.Entry) iter2.next();
data.put((String) pairs2.getKey(), (String) pairs2
.getValue());
}
holder.put(key, data);
} catch (JSONException e) {
Log.e("Transforming", "There was an error packaging JSON", e);
}
}
return holder;
}
5. JSONException:json中用到的异常
② JSONObject, JSONArray来构建和解析json文本
1. 构建Json文本
- // 假设现在要创建这样一个json文本
- // {
- // "phone" : ["12345678", "87654321"], // 数组
- // "name" : "yuanzhifei89", // 字符串
- // "age" : 100, // 数值
- // "address" : { "country" : "china", "province" : "jiangsu" }, // 对象
- // "married" : false // 布尔值
- // }
- try {
- // 首先最外层是{},是创建一个对象
- JSONObject person = new JSONObject();
- // 第一个键phone的值是数组,所以需要创建数组对象
- JSONArray phone = new JSONArray();
- phone.put("12345678").put("87654321");
- person.put("phone", phone);
- person.put("name", "yuanzhifei89");
- person.put("age", 100);
- // 键address的值是对象,所以又要创建一个对象
- JSONObject address = new JSONObject();
- address.put("country", "china");
- address.put("province", "jiangsu");
- person.put("address", address);
- person.put("married", false);
- } catch (JSONException ex) {
- // 键为null或使用json不支持的数字格式(NaN, infinities)
- throw new RuntimeException(ex);
- }
2. getType和optType api的使用
- try {
- // 所有使用的对象都是用上面创建的对象
- // 将第一个电话号码转换为数值和将名字转换为数值
- phone.getLong(0);
- person.getLong("name"); // 会抛异常,因为名字无法转换为long
- phone.optLong(0); // 代码内置的默认值
- phone.optLong(0, 1000); // 用户提供的默认值
- person.optLong("name");
- person.optLong("name", 1000); // 不像上面那样抛异常,而是返回1000
- } catch (JSONException ex) {
- // 异常处理代码
- }
③ JSONStringer来构建json文本
- try {
- JSONStringer jsonText = new JSONStringer();
- // 首先是{,对象开始。object和endObject必须配对使用
- jsonText.object();
- jsonText.key("phone");
- // 键phone的值是数组。array和endArray必须配对使用
- jsonText.array();
- jsonText.value("12345678").value("87654321");
- jsonText.endArray();
- jsonText.key("name");
- jsonText.value("yuanzhifei89");
- jsonText.key("age");
- jsonText.value(100);
- jsonText.key("address");
- // 键address的值是对象
- jsonText.object();
- jsonText.key("country");
- jsonText.value("china");
- jsonText.key("province");
- jsonText.value("jiangsu");
- jsonText.endObject();
- jsonText.key("married");
- jsonText.value(false);
- // },对象结束
- jsonText.endObject();
- } catch (JSONException ex) {
- throw new RuntimeException(ex);
- }
④ json文本解析类JSONTokener
主要方法 public Object nextValue(); 得到值
例子: 有一个JSON数据,格式为:
{
"phone" : ["12345678", "87654321"], // 数组
"name" : "yuanzhifei89", // 字符串
"age" : 100, // 数值
"address" : { "country" : "china", "province" : "jiangsu" }, // 对象
"married" : false // 布尔值
}
用JSONTokener对其进行解析如下
try {
JSONTokener jsonParser = new JSONTokener(JSON); // JSON为String类型
// 此时还未读取任何json文本,直接读取就是一个JSONObject对象。
// 如果此时的读取位置在"name" : 了,那么nextValue就是"yuanzhifei89"(String)
JSONObject person = (JSONObject) jsonParser.nextValue();
// 接下来的就是JSON对象的操作了
person.getJSONArray("phone");
person.getString("name");
person.getInt("age");
person.getJSONObject("address");
person.getBoolean("married");
} catch (JSONException ex) {
// 异常处理代码
}