Android中JSON使用總結(jié)

# 概念
JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式蝶怔。 易于閱讀和編寫。同時也易于機(jī)器解析和生成城看。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一個子集螟蒸。 JSON采用完全獨(dú)立于語言的文本格式,但是也使用了類似于C語言家族的習(xí)慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)餐屎。 這些特性使JSON成為理想的數(shù)據(jù)交換語言。

# JSON的結(jié)構(gòu)
JSON由如下兩種結(jié)構(gòu)建構(gòu):

  1. “名稱/值”對的集合(A collection of name/value pairs)玩祟。不同的語言中,它被理解為對象(object)屿聋,紀(jì)錄(record)空扎,結(jié)構(gòu)(struct),字典(dictionary)润讥,哈希表(hash table)转锈,有鍵列表(keyed list),或者關(guān)聯(lián)數(shù)組 (associative array)楚殿。
  2. 值的有序列表(An ordered list of values)撮慨。在大部分語言中,它被理解為數(shù)組(array)脆粥。

這些都是常見的數(shù)據(jù)結(jié)構(gòu)砌溺。事實(shí)上大部分現(xiàn)代計(jì)算機(jī)語言都以某種形式支持它們。這使得一種數(shù)據(jù)格式在同樣基于這些結(jié)構(gòu)的編程語言之間交換成為可能变隔。

JSON具有以下這些表現(xiàn)形式

  1. 對象(JSONObject):
    對象是一個無序的“‘名稱/值’對”集合规伐。一個對象以“{”(左括號)開始,“}”(右括號)結(jié)束匣缘。每個“名稱”后跟一個“:”(冒號)猖闪;“‘名稱/值’ 對”之間使用“,”(逗號)分隔鲜棠。


    JSONObject結(jié)構(gòu)圖
  2. 數(shù)組(JSONArray):
    數(shù)組是值(value)的有序集合。一個數(shù)組以“[”(左中括號)開始培慌,“]”(右中括號)結(jié)束豁陆。值之間使用“,”(逗號)分隔。


    JSONArray結(jié)構(gòu)圖

  3. 值(value)可以是雙引號括起來的字符串(string)吵护、數(shù)值(number)盒音、true、false何址、 null里逆、對象(object)或者數(shù)組(array)。這些結(jié)構(gòu)可以嵌套用爪。


    value結(jié)構(gòu)圖
  4. 字符串
    字符串(string)是由雙引號包圍的任意數(shù)量Unicode字符的集合原押,使用反斜線轉(zhuǎn)義。一個字符(character)即一個單獨(dú)的字符串(character string)偎血。
    字符串(string)與C或者Java的字符串非常相似诸衔。


    string結(jié)構(gòu)圖
  5. 數(shù)值
    數(shù)值(number)也與C或者Java的數(shù)值非常相似。除去未曾使用的八進(jìn)制與十六進(jìn)制格式颇玷。除去一些編碼細(xì)節(jié)笨农。


    圖片 1.png

    空白可以加入到任何符號之間。

JSON在Android中的使用

  1. android2.3提供的son解析類
android的json解析部分都在包org.json下帖渠,主要有以下幾個類:
JSONObject:可以看作是一個json對象
JSONStringer:json文本構(gòu)建類
JSONArray:可以看作是json的數(shù)組
JSONTokener:son解析類
JSONException:json中用到的異常
  1. JSONObject, JSONArray來構(gòu)建json文本
// 假設(shè)現(xiàn)在要創(chuàng)建這樣一個json文本
//  {
//      "phone" : ["12345678", "87654321"], // 數(shù)組
//      "name" : "yuanzhifei89", // 字符串
//      "age" : 100, // 數(shù)值
//      "address" : { "country" : "china", "province" : "jiangsu" }, // 對象
//      "married" : false // 布爾值
//  }
try {
    // 首先最外層是{}谒亦,是創(chuàng)建一個對象
    JSONObject person = new JSONObject();
    // 第一個鍵phone的值是數(shù)組,所以需要創(chuàng)建數(shù)組對象
    JSONArray phone = new JSONArray();
    phone.put("12345678").put("87654321");
    person.put("phone", phone);
    person.put("name", "yuanzhifei89");
    person.put("age", 100);
    // 鍵address的值是對象空郊,所以又要創(chuàng)建一個對象
    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不支持的數(shù)字格式(NaN, infinities)
    throw new RuntimeException(ex);
}
  1. getType和optType api的使用
    getType可以將要獲取的鍵的值轉(zhuǎn)換為指定的類型份招,如果無法轉(zhuǎn)換或沒有值則拋出JSONException
    optType也是將要獲取的鍵的值轉(zhuǎn)換為指定的類型,無法轉(zhuǎn)換或沒有值時返回用戶提供或這默認(rèn)提供的值
try {
    // 所有使用的對象都是用上面創(chuàng)建的對象
    // 將第一個電話號碼轉(zhuǎn)換為數(shù)值和將名字轉(zhuǎn)換為數(shù)值
    phone.getLong(0);
    person.getLong("name"); // 會拋異常狞甚,因?yàn)槊譄o法轉(zhuǎn)換為long
    phone.optLong(0); // 代碼內(nèi)置的默認(rèn)值
    phone.optLong(0, 1000); // 用戶提供的默認(rèn)值
    person.optLong("name");
    person.optLong("name", 1000); // 不像上面那樣拋異常锁摔,而是返回1000
} catch (JSONException ex) {
    // 異常處理代碼
}
  1. 除了上面的兩個類,還可以使用JSONStringer來構(gòu)建json文本
try {
    JSONStringer jsonText = new JSONStringer();
    // 首先是{哼审,對象開始谐腰。object和endObject必須配對使用
    jsonText.object();
    jsonText.key("phone");
    // 鍵phone的值是數(shù)組。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);
    // }涩盾,對象結(jié)束
    jsonText.endObject();
} catch (JSONException ex) {
    throw new RuntimeException(ex);
}
  1. json文本解析類JSONTokener
    按照RFC4627規(guī)范將json文本解析為相應(yīng)的對象十气。
    對于將json文本解析為對象,只需要用到該類的兩個api:
構(gòu)造方法 與 public Object nextValue();
//  {
//      "phone" : ["12345678", "87654321"], // 數(shù)組
//      "name" : "yuanzhifei89", // 字符串
//      "age" : 100, // 數(shù)值
//      "address" : { "country" : "china", "province" : "jiangsu" }, // 對象
//      "married" : false // 布爾值
//  }
private static final String JSON =
"{" +
    "   \"phone\" : [\"12345678\", \"87654321\"]," +
    "   \"name\" : \"yuanzhifei89\"," +
    "   \"age\" : 100," +
    "   \"address\" : { \"country\" : \"china\", \"province\" : \"jiangsu\" }," +
    "   \"married\" : false," +
"}";
try {
    JSONTokener jsonParser = new JSONTokener(JSON);
    // 此時還未讀取任何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) {
    // 異常處理代碼
}

其它的api基本就是用來查看json文本中的文本的

try {
    JSONTokener jsonParser = new JSONTokener(JSON);
    // 繼續(xù)向下讀8個json文本中的字符终畅。此時剛開始籍胯,即在{處
    jsonParser.next(8); //{    "phone竟闪。tab算一個字符
    // 繼續(xù)向下讀1個json文本中的字符
    jsonParser.next(); //"
    // 繼續(xù)向下讀取一個json文本中的字符。該字符不是空白杖狼、同時也不是注視中的字符
    jsonParser.nextClean(); //:
    // 返回當(dāng)前的讀取位置到第一次遇到'a'之間的字符串(不包括a)炼蛤。
    jsonParser.nextString('a'); //  ["12345678", "87654321"],    "n(前面有兩個空格)
    // 返回當(dāng)前讀取位置到第一次遇到字符串中(如"0089")任意字符之間的字符串,同時該字符是trimmed的蝶涩。(此處就是第一次遇到了89)
    jsonParser.nextTo("0089"); //me" : "yuanzhifei
    // 讀取位置撤銷一個
    jsonParser.back();
    jsonParser.next(); 
    // 讀取位置前進(jìn)到指定字符串處(包括字符串)
    jsonParser.skipPast("address");
    jsonParser.next(8); //" : { "c
    // 讀取位置前進(jìn)到執(zhí)行字符處(不包括字符)
    jsonParser.skipTo('m');
    jsonParser.next(8); //married"
} catch (JSONException ex) {
    // 異常處理代碼
}
  1. json中的null和java中的null
// json對象的成員為null可能有兩種情況:
// 1: 不出現(xiàn)該成員的名稱(對應(yīng)java中的null)
// 2: 成員值為null理朋。(對應(yīng)java中的JSONObject.NULL)
// 完整的Json
//  { 
//      "phone" : ["12345678", "87654321"], // 數(shù)組 
//      "name" : "yuanzhifei89", // 字符串 
//      "age" : 100, // 數(shù)值 
//      "address" : { "country" : "china", "province" : "jiangsu" }, // 對象 
//      "married" : false // 布爾值 
//  } 
// 第一種情況:不出現(xiàn)某成員的名稱(address)
String jsonText = "{" + 
    "   \"phone\" : [\"12345678\", \"87654321\"]," + 
    "   \"name\" : \"yuanzhifei89\"," + 
    "   \"age\" : 100," + 
    "   \"married\" : false," + 
"}";
try {
    JSONTokener t = new JSONTokener(jsonText);
    JSONObject obj = (JSONObject) t.nextValue();
    if (obj.optJSONObject("address") == null || obj.isNull("address")){
} catch (JSONException ex) {
    ex.printStackTrace();
}
// 第二種情況:成員值為null(address為null)
String jsonText = "{" + 
    "   \"phone\" : [\"12345678\", \"87654321\"]," + 
    "   \"name\" : \"yuanzhifei89\"," + 
    "   \"age\" : 100," + 
    "   \"address\" : null," + 
    "   \"married\" : false," + 
"}";
try {
    JSONTokener t = new JSONTokener(jsonText);
    JSONObject obj = (JSONObject) t.nextValue();
    // 應(yīng)該這樣判斷json是否為null
    if (obj.get("address") == JSONObject.NULL || obj.isNull("address")) {
} catch (JSONException ex) {
    ex.printStackTrace();
}

json中的對象不存在和java中的對應(yīng)關(guān)系:
json中的null對應(yīng)java中的JSONObject.NULL,所以jsonObj.put("key", JSONObject.NULL) 相當(dāng)于{"key" : null}
json中的不出現(xiàn)某成員對應(yīng)Java中的null绿聘,所以jsonObj.put("key", null)相當(dāng)于刪除該成員嗽上,即:{}

參考文檔

  1. JSON規(guī)范rfc4627
  2. json 官網(wǎng)介紹
  3. json入門參考
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市熄攘,隨后出現(xiàn)的幾起案子兽愤,更是在濱河造成了極大的恐慌,老刑警劉巖挪圾,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浅萧,死亡現(xiàn)場離奇詭異,居然都是意外死亡哲思,警方通過查閱死者的電腦和手機(jī)洼畅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棚赔,“玉大人帝簇,你說我怎么就攤上這事】恳妫” “怎么了己儒?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長捆毫。 經(jīng)常有香客問我,道長冲甘,這世上最難降的妖魔是什么绩卤? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮江醇,結(jié)果婚禮上濒憋,老公的妹妹穿的比我還像新娘。我一直安慰自己陶夜,他們只是感情好凛驮,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著条辟,像睡著了一般黔夭。 火紅的嫁衣襯著肌膚如雪宏胯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天本姥,我揣著相機(jī)與錄音肩袍,去河邊找鬼。 笑死婚惫,一個胖子當(dāng)著我的面吹牛氛赐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播先舷,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼艰管,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蒋川?” 一聲冷哼從身側(cè)響起牲芋,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尔破,沒想到半個月后街图,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡懒构,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年餐济,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胆剧。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡絮姆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秩霍,到底是詐尸還是另有隱情篙悯,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布铃绒,位于F島的核電站鸽照,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颠悬。R本人自食惡果不足惜矮燎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赔癌。 院中可真熱鬧诞外,春花似錦、人聲如沸灾票。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至既们,卻和暖如春濒析,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贤壁。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工悼枢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脾拆。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓馒索,卻偏偏與公主長得像,于是被迫代替她去往敵國和親名船。 傳聞我的和親對象是個殘疾皇子绰上,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 2017年據(jù)說是找工作的寒冬,作為一個Android開發(fā)渠驼,下面的一些問題可能在面試的時候遇到哦: 1蜈块、java 內(nèi)...
    小相柳閱讀 513評論 0 4
  • 久違的新文章發(fā)布。迷扇。我的鍋這篇文章是在寫的太長百揭,可以慢慢看一下,偽代碼蜓席,畢竟簡書上面器一,望大家見諒!3凇祈秕!先看官方文檔...
    wyatt_plus閱讀 1,625評論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)雏胃,斷路器请毛,智...
    卡卡羅2017閱讀 134,626評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法瞭亮,內(nèi)部類的語法方仿,繼承相關(guān)的語法,異常的語法统翩,線程的語...
    子非魚_t_閱讀 31,597評論 18 399
  • “小柚子仙蚜,你追不上我的!”稚嫩的聲音從吳家的后花園里傳出來唆缴。男生在前面跑著,這個男生后面有個女生追著他跑黍翎。 ...
    小云陌閱讀 156評論 0 1