摘要
XML——這種用于表示客戶端與服務(wù)器間數(shù)據(jù)交換有效負(fù)載的格式,幾乎已經(jīng)成了Web services的同義詞。然而,由于Ajax和REST技術(shù)的出現(xiàn)影響了應(yīng)用程序架構(gòu),這迫使人們開(kāi)始尋求`XML的替代品,如:JavaScript Object Notation(JSON)。
JSON 作為一種更輕、更友好的 Web services客戶端的格式(多采用瀏覽器的形式或訪問(wèn) REST風(fēng)格 Web服務(wù)的Ajax應(yīng)用程序的形式)引起了 Web 服務(wù)供應(yīng)商的注意。
本文將闡述JSON在Web services設(shè)計(jì)中備受推崇的原因,以及它作為XML替代方案的主要優(yōu)勢(shì)和局限性。文中還會(huì)深入探討:隨著相應(yīng)的Web 服務(wù)客戶端選擇使用JSON,如何才能便捷地在Java Web services中生成JSON輸出。
XML的十字路口: 瀏覽器和 Ajax
XML設(shè)計(jì)原理已經(jīng)發(fā)布了將近十年。時(shí)至今日,這種標(biāo)記語(yǔ)言已經(jīng)在廣闊的軟件應(yīng)用領(lǐng)域中占據(jù)了主導(dǎo)地位。從Java、.NET等主流平臺(tái)中的配置和部署描述符到應(yīng)用集成場(chǎng)景中更復(fù)雜的應(yīng)用,XML與生俱來(lái)的語(yǔ)言無(wú)關(guān)性使之在軟件架構(gòu)師心目中占據(jù)著獨(dú)特的地位。但即便最著名的XML權(quán)威也不得不承認(rèn):在某些環(huán)境中,XML的使用已經(jīng)超出了它自身能力的極限。
圍繞Ajax原理構(gòu)建的那些Web應(yīng)用程序最能說(shuō)明XML的生存能力,從這一點(diǎn)來(lái)看,一種新的有效負(fù)載格式的發(fā)展壯大也得益于XML。這種新的有效負(fù)載格式就是JavaScript Object Notation (JSON)。在探索這種新的標(biāo)記語(yǔ)言的復(fù)雜性之前,首先來(lái)分析一下在這種獨(dú)特的設(shè)計(jì)形式中,XML具有哪些局限性。
Ajax建立了一個(gè)用于從遠(yuǎn)程Web services發(fā)送和接收數(shù)據(jù)的獨(dú)立信道,從而允許Web程序執(zhí)行信道外(out-of-band)客戶端/服務(wù)器調(diào)用。通俗地說(shuō),Ajax程序中的更新和導(dǎo)航序列在典型的客戶端/服務(wù)器環(huán)境之外完成,在后臺(tái)(即信道外)接受到信息后,必須進(jìn)行一次完整的屏幕刷新。更多背景信息,請(qǐng)參閱David Teare的 Ajax簡(jiǎn)介(Dev2Dev)。
這些應(yīng)用程序更新通常是通過(guò)REST風(fēng)格(RESTful)Web services獲得的,一旦被用戶的瀏覽器接收到,就需要整合到HTML頁(yè)面的總體布局之中,這正是XML發(fā)揮強(qiáng)大力量的場(chǎng)合。盡管近年來(lái),腳本語(yǔ)言支持和插件支持已使大多數(shù)主流瀏覽器的功能得到了強(qiáng)化,但許多編程任務(wù)依然難于開(kāi)展,其中之一就是操縱或處理文本,這通常是使用DOM實(shí)現(xiàn)的。
采用DOM的復(fù)雜性源于其基于函數(shù)的根,這使得對(duì)數(shù)據(jù)樹(shù)的簡(jiǎn)單修改或訪問(wèn)都需要進(jìn)行無(wú)數(shù)次方法調(diào)用。此外,眾所周知,DOM在各種瀏覽器中的實(shí)現(xiàn)細(xì)節(jié)不盡相同,這一過(guò)程將帶來(lái)極為復(fù)雜的編程模式,其跨瀏覽器兼容性出現(xiàn)問(wèn)題的可能性極大。接下來(lái)的問(wèn)題顯而易見(jiàn),那就是:如何使一種標(biāo)記語(yǔ)言輕松集成到HTML頁(yè)面中以滿足Ajax的要求?
問(wèn)題的答案就是:利用所有主流瀏覽器中的一種通用組件——JavaScript引擎。XML需要使用DOM之類的機(jī)制來(lái)訪問(wèn)數(shù)據(jù)并將數(shù)據(jù)整合到布局之中,采用這種方法,我們不再使用像XML這樣的格式來(lái)交付Ajax更新,而是采用一種更為簡(jiǎn)單直觀的方式,采用JavaScript引擎自然匹配的格式——也就是JSON。
既然已經(jīng)明確了JSON與XML和Ajax之間的關(guān)系,下面將進(jìn)一步探討JSON背后的技術(shù)細(xì)節(jié)。
JSON剖析:優(yōu)點(diǎn)和不足
對(duì)于JSON,首先要明白JSON和XML一樣也是一種簡(jiǎn)單文本格式。相對(duì)于XML,它更加易讀、更便于肉眼檢查。在語(yǔ)法的層面上,JSON與其他格式的區(qū)別是在于分隔數(shù)據(jù)的字符,JSON中的分隔符限于單引號(hào)、小括號(hào)、中括號(hào)、大括號(hào)、冒號(hào)和逗號(hào)。下圖是一個(gè)JSON有效負(fù)載:
{"addressbook": {"name": "Mary Lebow",
"address": {
"street": "5 Main Street"
"city": "San Diego, CA",
"zip": 91912,
},
"phoneNumbers": [
"619 332-3452",
"664 223-4667"
]
}
}
將上面的JSON有效負(fù)載用XML改寫,如下:
<addressbook>
<name>Mary Lebow</name>
<address>
<street>5 Main Street</street>
<city zip="91912"> San Diego, CA </city>
<phoneNumbers>
<phone>619 332-3452</phone>
<phone>664 223-4667</phone>
</phoneNumbers>
</address>
</addressbook>
是不是很相似?但它們并不相同。下面將詳細(xì)闡述采用JSON句法的優(yōu)點(diǎn)和不足。
優(yōu)點(diǎn)
乍看上去,使用JSON的數(shù)據(jù)分隔符的優(yōu)點(diǎn)可能并不那么明顯,但存在一個(gè)根本性的緣由:它們簡(jiǎn)化了數(shù)據(jù)訪問(wèn)。使用這些數(shù)據(jù)分隔符時(shí), JavaScript引擎對(duì)數(shù)據(jù)結(jié)構(gòu)(如字符串、數(shù)組、對(duì)象)的內(nèi)部表示恰好與這些符號(hào)相同。
這將開(kāi)創(chuàng)一條比DOM技術(shù)更為便捷的數(shù)據(jù)訪問(wèn)途徑。下面列舉幾個(gè)JavaScript代碼片段來(lái)說(shuō)明這一過(guò)程,這些代碼片段會(huì)訪問(wèn)先前的JSON代碼片段中的信息:
• 訪問(wèn)JSON中的名稱: addressbook.name
• 訪問(wèn)JSON中的地址: addressbook.address.street
• 訪問(wèn)JSON中的電話號(hào)碼第一位:addressbook.address.phoneNumbers[0]
如果您具備DOM編程經(jīng)驗(yàn),就能很快地看出區(qū)別;新手可以參看 Document Object Model 的這一外部資源,這里提供了關(guān)于數(shù)據(jù)導(dǎo)航的實(shí)例。
JSON的另一個(gè)優(yōu)點(diǎn)是它的非冗長(zhǎng)性。在XML中,打開(kāi)和關(guān)閉標(biāo)記是必需的,這樣才能滿足標(biāo)記的依從性;而在JSON中,所有這些要求只需通過(guò)一個(gè)簡(jiǎn)單的括號(hào)即可滿足。在包含有數(shù)以百計(jì)字段的數(shù)據(jù)交換中,傳統(tǒng)的XML標(biāo)記將會(huì)延長(zhǎng)數(shù)據(jù)交換時(shí)間。目前還沒(méi)有正式的研究表明JSON比XML有更高的線上傳輸效率;人們只是通過(guò)簡(jiǎn)單的字節(jié)數(shù)比較發(fā)現(xiàn),對(duì)于等效的JSON和XML有效負(fù)載,前者總是小于后者。至于它們之間的差距有多大,特別是在新的XML壓縮格式下它們的差距有多大,有待進(jìn)一步的研究。
此外,JSON受到了擅長(zhǎng)不同編程語(yǔ)言的開(kāi)發(fā)人員的青睞。這是因?yàn)闊o(wú)論在Haskell中或 Lisp中,還是在更為主流的C#和PHP中,開(kāi)發(fā)都可以方便地生成JSON(詳見(jiàn) 參考資料)。
不足
和許多好東西都具有兩面性一樣,JSON的非冗長(zhǎng)性也不例外,為此JSON丟失了XML具有的一些特性。命名空間允許不同上下文中的相同的信息段彼此混合,然而,顯然在JSON中已經(jīng)找不到了命名空間。JSON與XML的另一個(gè)差別是屬性的差異,由于JSON采用冒號(hào)賦值,這將導(dǎo)致當(dāng)XML轉(zhuǎn)化為JSON時(shí),在標(biāo)識(shí)符(XML CDATA)與實(shí)際屬性值之間很難區(qū)分誰(shuí)應(yīng)該被當(dāng)作文本考慮。
另外,JSON片段的創(chuàng)建和驗(yàn)證過(guò)程比一般的XML稍顯復(fù)雜。從這一點(diǎn)來(lái)看,XML在開(kāi)發(fā)工具方面領(lǐng)先于JSON。盡管如此,為了消除您對(duì)這一領(lǐng)域可能存在的困惑,下節(jié)將介紹一些最為成熟的JSON開(kāi)發(fā)