JSON(JavaScript Object Notation)是一種基於文本的數據交換格式。不管你的應用是用哪一種開發語言編寫的(Java/EE,Ruby,PHP,C#/.Net等等),你均可以使用JSON來經過網絡進行數據交互和處理。幾乎全部的編程語言都有很好的庫或第三方工具來提供基於JSON的API支持,所以你能夠很是方便地使用任何本身喜歡的編程語言來處理JSON數據。而另外一方面隨着REST、像MongoDB這樣的NoSQL技術或標準的普遍使用,JSON也正成爲一種被推薦的數據交互格式。php
JSON是在2001年,由Douglas Crockford建立的,而且被IETF(Internet Engineering Task Force)定義爲RFC 4627標準,詳請參考:http://tools.ietf.org/html/rfc4627。JSON的媒體類型被定義爲 application/json,而文件的後綴爲.json。html
JSON是一種簡單數據格式,它有三種數據結構:java
一個有效的JSON文檔須要被包含在一對花括號內{ JSON-Data }
ios
請注意,有些開發社區或線上文檔直接將上面的JSON文檔稱爲JSON字符串,這二者的意思是同樣的。git
JSON被認爲是XML的很好替代者。由於JSON的可讀性很是好,並且它沒有像XML那樣包含不少冗餘的元素標籤,這使得應用在使用JSON進行網絡傳輸以及進行解析處理的速度更快,效率更高。github
鍵值對是JSON中最基本的數據結構:{ 「firstName」: 「John」}
ajax
在上面的例子中屬性"firstName"是用一對雙引號括起來的一個字符串。而它的值"John"在這個例子中也是一個字符串,固然它還能夠是其餘類型,具體可參考後面數據類型的章節。在市面上不少的產品或技術聲稱他們使用的是JSON數據格式,但他們在定義屬性時,並無用雙引號將屬性名稱括起來,其實這是違反JSON定義標準的。編程
一個JSON對象是包含了一組未排序鍵值對的集合。下面例子中的address就是一個JSON對象:json
{ 「address」 : { 「line1」 : 「555 Main Street」, 「city」 : 「Denver」, 「stateOrProvince」 : 「CO」, 「zipOrPostalCode」 : 「80202」, 「country」 : 「USA」 } }
上面的例子中address對象包含了5個屬性,它們之間用,進行分割。api
JSON中[]來包含數組元素,參考下面的例子:
{ 「people」 : [ { 「firstName」: 「John」, 「lastName」: 「Smith」, 「age」: 35 }, { 「firstName」: 「Jane」, 「lastName」: 「Smith」, 「age」: 32 } ] }
JSON中的數值(鍵值對中的值)能夠是如下任意一種:
Object
Array
String
Number
Boolean
null
數值類型數據能夠是整型也能夠是雙精度的浮點型數據。下面是一些示例:
「age」: 29「cost」: 299.99「temperature」: -10.5「speed_of_light」: 1.23e11「speed_of_light」: 1.23e+11「speed_of_light」: 1.23E11「speed_of_light」: 1.23E+11
上面的屬性(如age等)都是用雙引號括起來的字符串,而數值是不須要用雙引號括起來的。你能夠在數值前加上-號來表示負數,也能夠採用科學計數法。但不能在數值前加0或使用16進制來表示一個數值。
JSON中的Boolean值能夠用true或false來表示。不用加{}{ 「emailValidated」 : true}
Boolean值也不須要使用雙引號來修飾。
嚴格來講null並非一個數據類型,但它很是重要,它表示一個屬性或元素沒有值。所以請注意 ' ' 表示的是空字符串,而null表示的纔是空值。{ 「age」 : null}
JSON不容許在JSON文檔或字符串中添加註釋。註釋功能最先在JSON中是存在的,但開發者們錯誤地使用了它來輔助JSON數據的解析,當Douglas Crockford意識到這種很差的使用實踐後,便取消了註釋功能,以保證JSON在不一樣計算平臺間做爲交互數據格式的特性。
你可能已經注意到了在以前的例子中,全部的屬性名稱都使用了駝峯式的命名規則。這並非JSON的一個標準要求,但這可以幫助提升JSON文檔的可讀性,所以做爲一個事實標準在全部JSON應用中被使用。
Douglas Crockford 在他的JSON網站http://www.json.org/中,給出了全部JSON語法語義的說明。另外還有一個iOS App JSON Pro FREE能夠用來經過示例學習或參考JSON。
一個文本文檔或字符串必須遵照JSON的語法定義,才能被視做一個有效的JSON文檔。JSON文檔是否有效很是重要,由於它直接決定了,你的JSON數據可否在不一樣的應用中被正確地解析和使用。JSONLint提供了一個可交互的Web版JSON校驗工具,你只須要將你的JSON文檔粘貼進去,並點擊校驗按鈕,它便會自動進行校驗,並將問題顯示在下方。
在上面這個例子中,這個JSON對象的city屬性沒有加上雙引號,致使校驗失敗。在返回的提示中,顯示了「Expecting 'STRING', got 'undefined'」錯誤。
JSONLint也提供了一個能夠在Chrome中直接使用的插件。
在應用中手工編寫JSON文檔,會很枯燥並容易出錯。爲了防止這樣的惡錯誤 ,你可使用JSONPad或JSON Editor Online這樣的工具,它們可以幫助你構建JSON邏輯模型(相似於UML),而後經過模型生成JSON文檔。
[ JSON Editor Online] (http://jsoneditoronline.org/) 是一個在線JSON數據建模工具,他也提供了一個Chrome插件可使用。
Firefox和Chrome都提供了一些很好的插件方便開發人員查看或處理JSON數據。
Rest Client是Firefox中的一個擴展應用。他可以幫助開發人員在瀏覽器中調試REST風格的Web Service。它最大的優勢是能將返回的JSON數據結果,以很好的格式顯示出來。
JSONView是一個FireFox和Chrome上的插件,可以很好地將JSON數據打印出來,從而大大提升了JSON數據的可讀性。
AJAX多是使用JSON數據中最多見的場景了。下面的這段代碼示例,經過jQuery來調用一個REST風格的Web Service,並處理返回的JSON對象。
$.getJSON(‘http://example/service/addresses/home/1’, function(data) { var address = JSON.parse(data); console.log(「Address Line 1 = 「 + address.line1); } );
在上面的這段代碼中,$getJSON(這是一種jQuery中$.ajax()標準調用的一種縮寫形式)會發起一個HTTP GET 請求,調用Web Service,以後在它的隱式回調函數中,獲取返回的data數據,並經過JSON.parse()方法將返回的數據轉換爲JSON對象。以後即可以像獲取普通屬性那樣(address.line1)獲取對象的屬性數值了。
Jackson是JAVA中用來處理JSON的一個第三方庫。它頗有名,而且提供了一組很是好用的JSON API。下面就是它的一個例子:
import java.io.Writer; import java.io.StringWriter; import org.codehaus.jackson.map.ObjectMapper; public class Address { private String line1; private String city; private String stateOrProvince; private String zipOrPostalCode; private String country; public Address() {} public String getLine1() { return line1; } public void setLine1(line1) { this.line1 = line1; } // Remaining getters and setters ... } Address addrOut = new Address(); // Call setters to populate addrOut … ObjectMapper mapper = new ObjectMapper(); // Reuse this. // Marshal Address object to JSON String. Writer writer = new StringWriter(); mapper.writeValue(writer, addrOut); System.out.println(writer.toString()); // Unmarshal Address object from JSON String. String addrJsonStr = 「{「 + 「\」address\」 : {「 + 「\」line1\」 : \」555 Main Street\」,」 + 「\」city\」 : \」Denver\」,」 「\」stateOrProvince\」 : \」CO\」,」 「\」zipOrPostalCode\」 : \」80202\」,」 + 「\」country\」 : \」USA\」」 + 「}」 + 「}」; Address addrIn = mapper.readValue(addrJsonStr, Address.class);
除了Jackson以外,還有一些其餘基於JAVA的第三方JSON API庫。
API
Source
Google GSON
http://code.google.com/p/google-json/SOJO
http://sojo.sourceforge.net/org.json (by DouglasCrockford)
http://www.json.org/javajson-lib
http://sourceforge.net/projects/json-lib/json-io
http://code.google.com/p/json-iojsontools
http://jsontools.berlios.de/jsonbeans
http://code.google.com/p/jsonbeans/
Ruby中也有不少與JSON相關的第三方庫,而JSON gem是Ruby自帶的,下面就是它的用法:
require ‘json’ class Address attr_accessor :line1, :city, :state_or_province, :zip_or_postal_code, :country def initialize(line1=’’, city=’’, state_or_province=’’, zip_or_postal_code=’’, country=’’) @line1 = line1 @city = city @state_or_province = state_or_province @zip_or_postal_code = zip_or_postal_code @country = country end def to_json to_hash.to_json end def from_json!(str) JSON.parse(str).each { |var, val| send(「#{var}=」, val) } end private def to_hash Hash[instance_variables.map { |var| [var[1..-1].to_sym, send(var[1..-1])] }] end end
JSON gem的to_json方法將字符串或哈希轉換爲JSON。Address對象的to_json方法經過將它的成員轉換成哈希再對哈希值調用to_json,最終將一個Address對象轉換爲JSON格式。
addr1 = Address.new(‘555 Main Street’, ‘Denver’, ‘CO’, ‘80231’, ‘US’) puts addr1.to_json # Outputs the following … {「line1」:」555 Main Street」,」city」:」Denver」,」state_or_ province」:」CO」,」zip_or_postal_code」:」80231」,」country」:」US」}
JSON gem的JSON.pase方法則將JSON字符串轉換爲哈希。Address對象的from_jason!方法接收一個JSON字符串,而後調用JSON.parse來轉換哈希,而後再在對象上分別設置這些哈希的值。
json_addr = <<END{ 「line1」 : 「999 Broadway」, 「city」 : 「Anytown」, 「state_or_province」 : 「CA」, 「zip_or_postal_code」 : 「90210」, 「country」 : 「USA」}ENDaddr2 = Address.newaddr2.from_json!(json_addr)
除了JSON gem以外,還有如下一些Ruby的JSON第三方庫
API
Source
ActiveSupport JSON
http://api.rubyonrails.org/classes/ActiveSupport/JSON.html
Yajl
https://github.com/brianmario/yajl-ruby
Oj
https://github.com/ohler55/oj
JSON與RUBY ON RAILS
Ruby on Rails也提供了將Ruby對象轉換爲JSON的功能。下面的例子中的Controller使用了render方法將一個Ruby對象以JSON數據的格式進行輸出。
Rails中的ApplicationController會負責對象與JSON數據之間的互相轉換 。所以,不須要額外調用to_json方法。
JSON Schema用來定義JSON文檔的結構,它能夠被用來驗證和校驗發送或收到的JSON文檔是否有效和規範。JSON Schema自己也是用JSON格式編寫的,它的具體定義能夠參考http://json-schema.org。
下面是JSON Schema的部分結構定義:
結構
描述
type
對象的數據類型,如Object,array,string,number 等
$schema
提供Schema版本的URI
required
true/false
id
數據元素id
properties
數據元素的校驗屬性,包括最大值,最小值,枚舉等
下面是JSON Schema的一個示例
「type」: 「object」,「$schema」: 「http://json-schema.org/draft-03/schema」,「id」: 「#」,「required」: true,「properties」: { 「registrants」: { 「type」: 「array」, 「id」: 「registrants」, 「required」: true, 「items」: { 「type」: 「object」, 「required」: false, 「properties」: { 「address」: { 「type」: 「object」, 「id」: 「address」, 「required」: true, 「properties」: { 「city」: { 「type」: 「string」, 「id」: 「city」, 「required」: true }, 「country」: { 「type」: 「string」, 「id」: 「country」, 「required」: false }, 「line1」: { 「type」: 「string」, 「id」: 「line1」, 「required」: true }, 「line2」: { 「type」: 「string」, 「id」: 「line2」, 「required」: false }, 「postalCode」: { 「type」: 「string」, 「id」: 「postalCode」, 「required」: true }, 「premise」: { 「type」: 「string」, 「id」: 「premise」, 「required」: true, 「enum」: [ 「work」, 「home」, 「other」 ] }, 「stateOrProvince」: { 「type」: 「string」, 「id」: 「stateOrProvince」, 「required」: true } } }, 「firstName」: { 「type」: 「string」, 「id」: 「firstName」, 「required」: true }, 「lastName」: { 「type」: 「string」, 「id」: 「lastName」, 「required」: true }, 「phoneNumber」: { 「type」: 「object」, 「id」: 「phoneNumber」, 「required」: true, 「properties」: { 「channel」: { 「type」: 「string」, 「id」: 「channel」, 「required」: true, 「enum」: [ 「cell」, 「work」, 「home」 ] }, 「number」: { 「type」: 「string」, 「id」: 「number」, 「required」: true } } } } } } } }
在上面的Schema中對JSON對象作了如下約束:
registrants必須是一個數組對象
phoneNumber的channel必須是cell, work, fax, home中的一個
address的premise必須是home, work, other中的一個。
一個使用上述JSON Schema的Web Service能夠解析和處理下面這個JSON文檔:
{ "registrants": [ { "firstName": "Fred", "lastName": "Smith", "phoneNumber": { "channel": "cell", "number": "303-555-1212" }, "address": { "premise": "home", "line1": "555 Broadway NW", "line2": "# 000", "city": "Denver", "stateOrProvince": "CO", "postalCode": "88888", "country": "USA" } } ]}
JSON Schema 生成器
咱們可使用JSON Schema生成器來爲一個有效的JSON文檔生成對應的Schema。你須要訪問(www.jsonschema.net),而後按照如下步驟操做:
將你的JSON文檔粘貼到右側文本框
選擇JSON輸入選項
點擊Generate Schema按鈕
JSON Schema 校驗器
咱們能夠用JSON Schema Validator來保證咱們的JSON文檔時有效的。下面是針對不一樣開發語言的一些常見的JSON Schema 校驗器。
校驗器
編程語言
項目地址
JSV
JavaScript
https://github.com/garycourt/JSV
Ruby JSON Schema Validator
Ruby
https://github.com/hoxworth/jsonschema
json-schemavalidator
Java
https://github.com/fge/json-schema-validator
php-json-schema(by MIT)
PHP
https://github.com/hasbridge/php-json-schema
JSON.Net
.NET
http://james.newtonking.com/projects/json-net.aspx
除了上面這些與編程語言相關的校驗器以外,你還能夠直接使用在線的JSON Schema校驗器( http://json-schema-validator.herokuapp.com ),將Schema和JSON文檔粘貼到左側的文本框中,而後點擊Validate按鈕,校驗的結果就會顯示在屏幕右側。總結以上,咱們已經初步瞭解了JSON的核心定義和用法,但對於JSON自己來講咱們還只是瞭解了其中很小的一部分,還有許多與它相關的工具或技術可使用。JSON做爲一個數據標準,它已經逐步替代XML成爲Internet上最受歡迎的交互數據格式。簡書籤約做者:技匠,以上內容歡迎你們分享到朋友圈/微博等。如需轉載,請經過簡信聯繫受權。謝謝你們!