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文本

  1. // 假设现在要创建这样一个json文本    
  2. //  {    
  3. //      "phone" : ["12345678", "87654321"], // 数组    
  4. //      "name" : "yuanzhifei89", // 字符串    
  5. //      "age" : 100, // 数值    
  6. //      "address" : { "country" : "china", "province" : "jiangsu" }, // 对象    
  7. //      "married" : false // 布尔值    
  8. //  }    
  9.     
  10. try {    
  11.     // 首先最外层是{},是创建一个对象    
  12.     JSONObject person = new JSONObject();    
  13.     // 第一个键phone的值是数组,所以需要创建数组对象    
  14.     JSONArray phone = new JSONArray();    
  15.     phone.put("12345678").put("87654321");    
  16.     person.put("phone", phone);    
  17.     
  18.     person.put("name", "yuanzhifei89");    
  19.     person.put("age", 100);    
  20.     // 键address的值是对象,所以又要创建一个对象    
  21.     JSONObject address = new JSONObject();    
  22.     address.put("country", "china");    
  23.     address.put("province", "jiangsu");    
  24.     person.put("address", address);      
  25.     person.put("married", false);    
  26. catch (JSONException ex) {    
  27.     // 键为null或使用json不支持的数字格式(NaN, infinities)    
  28.     throw new RuntimeException(ex);    
  29. }    

2. getType和optType api的使用 

  1. try {    
  2.     // 所有使用的对象都是用上面创建的对象    
  3.     // 将第一个电话号码转换为数值和将名字转换为数值    
  4.     phone.getLong(0);    
  5.     person.getLong("name"); // 会抛异常,因为名字无法转换为long          
  6.     phone.optLong(0); // 代码内置的默认值    
  7.     phone.optLong(0, 1000); // 用户提供的默认值    
  8.     person.optLong("name");    
  9.     person.optLong("name", 1000); // 不像上面那样抛异常,而是返回1000    
  10. catch (JSONException ex) {    
  11.     // 异常处理代码    
  12. }    

③ JSONStringer来构建json文本

  1. try {    
  2.     JSONStringer jsonText = new JSONStringer();    
  3.     // 首先是{,对象开始。object和endObject必须配对使用    
  4.     jsonText.object();    
  5.         
  6.     jsonText.key("phone");    
  7.     // 键phone的值是数组。array和endArray必须配对使用    
  8.     jsonText.array();    
  9.     jsonText.value("12345678").value("87654321");    
  10.     jsonText.endArray();    
  11.         
  12.     jsonText.key("name");    
  13.     jsonText.value("yuanzhifei89");    
  14.     jsonText.key("age");    
  15.     jsonText.value(100);    
  16.         
  17.     jsonText.key("address");    
  18.     // 键address的值是对象    
  19.     jsonText.object();    
  20.     jsonText.key("country");    
  21.     jsonText.value("china");    
  22.     jsonText.key("province");    
  23.     jsonText.value("jiangsu");    
  24.     jsonText.endObject();    
  25.         
  26.     jsonText.key("married");    
  27.     jsonText.value(false);    
  28.         
  29.     // },对象结束    
  30.     jsonText.endObject();    
  31. catch (JSONException ex) {    
  32.     throw new RuntimeException(ex);    
  33. }    

④ 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) {    

// 异常处理代码    

}