使用 jQuery 簡化 Ajax 開發

來源:互聯網
上載者:User
JSON 入門指南


 

 

層級: 初級

廖 雪峰, 撰稿人

2008 年 8 月 22 日

JSON 即 JavaScript Object Natation,它是一種輕量級的資料交換格式,非常適合於伺服器與 JavaScript 的互動。本文將快速講解 JSON 格式,並通過程式碼範例示範如何分別在用戶端和伺服器端進行 JSON 格式資料的處理。

儘管有許多宣傳關於 XML 如何擁有跨平台,跨語言的優勢,然而,除非應用於 Web Services,否則,在普通的 Web 應用程式中,開發人員經常為 XML 的解析傷透了腦筋,無論是伺服器端產生或處理 XML,還是用戶端用 JavaScript 解析 XML,都常常導致複雜的代碼,極低的開發效率。實際上,對於大多數 Web 應用程式來說,他們根本不需要複雜的 XML 來傳輸資料,XML 的擴充性很少具有優勢,許多 AJAX 應用甚至直接返回 HTML 片段來構建動態 Web 頁面。和返回 XML 並解析它相比,返回 HTML 片段大大降低了系統的複雜性,但同時缺少了一定的靈活性。

現在, JSON 為 Web 應用程式開發人員提供了另一種資料交換格式。讓我們來看看 JSON 到底是什麼,同 XML 或 HTML 片段相比,JSON 提供了更好的簡單性和靈活性。

JSON 資料格式解析

和 XML 一樣,JSON 也是基於純文字的資料格式。由於 JSON 天生是為 JavaScript 準備的,因此,JSON 的資料格式非常簡單,您可以用 JSON 傳輸一個簡單的 String,Number,Boolean,也可以傳輸一個數組,或者一個複雜的 Object 對象。

String,Number 和 Boolean 用 JSON 表示非常簡單。例如,用 JSON 表示一個簡單的 String “ abc ”,其格式為:

"abc"

除了字元 "\/ 和一些控制符(\b\f\n\r\t)需要編碼外,其他 Unicode 字元可以直接輸出。是一個 String 的完整表示結構:

圖 1. String 的完整表示結構

一個 Number 可以根據整型或浮點數表示如下:

圖 2. Number 的表示結構

這與絕大多數程式設計語言的表示方法一致,例如:

12345(整數) -3.9e10(浮點數)

Boolean 類型表示為 truefalse 。此外,JavaScript 中的 null 被表示為 null,注意,truefalsenull 都沒有雙引號,否則將被視為一個 String 。

JSON 還可以表示一個數組對象,使用 [] 包含所有元素,每個元素用逗號分隔,元素可以是任意的 Value,例如,以下數組包含了一個 String,Number,Boolean 和一個 null:

["abc",12345,false,null]

Object 對象在 JSON 中是用 {} 包含一系列無序的 Key-Value 索引值對錶示的,實際上此處的 Object 相當於 Java 中的 Map<String, Object>,而不是 Java 的 Class 。注意 Key 只能用 String 表示。

例如,一個 Address 對象包含如下 Key-Value:

city:Beijing  street:Chaoyang Road  postcode:100025(整數)

用 JSON 表示如下:

{"city":"Beijing","street":" Chaoyang Road ","postcode":100025}

其中 Value 也可以是另一個 Object 或者數組,因此,複雜的 Object 可以巢狀表格示,例如,一個 Person 對象包含 name 和 address 對象,可以表示如下:

{"name":"Michael","address":    {"city":"Beijing","street":" Chaoyang Road ","postcode":100025}}

JavaScript 處理 JSON 資料

上面介紹了如何用 JSON 表示資料,接下來,我們還要解決如何在伺服器端產生 JSON 格式的資料以便發送到用戶端,以及用戶端如何使用 JavaScript 處理 JSON 格式的資料。

我們先討論如何在 Web 頁面中用 JavaScript 處理 JSON 資料。我們通過一個簡單的 JavaScript 方法就能看到用戶端如何將 JSON 資料表示給使用者:

function handleJson() {   var j={"name":"Michael","address":      {"city":"Beijing","street":" Chaoyang Road ","postcode":100025}  };   document.write(j.name);   document.write(j.address.city);  }

假定伺服器返回的 JSON 資料是上文的:

{"name":"Michael","address":    {"city":"Beijing","street":" Chaoyang Road ","postcode":100025}}

只需將其賦值給一個 JavaScript 變數,就可以立刻使用該變數並更新頁面中的資訊了,相比 XML 需要從 DOM 中讀取各種節點而言,JSON 的使用非常容易。我們需要做的僅僅是發送一個 Ajax 請求,然後將伺服器返回的 JSON 資料賦值給一個變數即可。有許多 Ajax 架構早已包含了處理 JSON 資料的能力,例如 Prototype(一個流行的 JavaScript 庫:http://prototypejs.org)提供了 evalJSON() 方法,能直接將伺服器返回的 JSON 文本變成一個 JavaScript 變數:

new Ajax.Request("http://url", {   method: "get",   onSuccess: function(transport) {     var json = transport.responseText.evalJSON();     // TODO: document.write(json.xxx);   }  });

伺服器端輸出 JSON 格式資料

下面我們討論如何在伺服器端輸出 JSON 格式的資料。以 Java 為例,我們將示範將一個 Java 對象編碼為 JSON 格式的文本。

將 String 對象編碼為 JSON 格式時,只需處理好特殊字元即可。另外,必須用 (") 而非 (') 表示字串:

  static String string2Json(String s) {     StringBuilder sb = new StringBuilder(s.length()+20);     sb.append('\"');     for (int i=0; i<s.length(); i++) {         char c = s.charAt(i);         switch (c) {         case '\"':             sb.append("\\\"");             break;         case '\\':             sb.append("\\\\");             break;         case '/':             sb.append("\\/");             break;         case '\b':             sb.append("\\b");             break;         case '\f':             sb.append("\\f");             break;         case '\n':             sb.append("\\n");             break;         case '\r':             sb.append("\\r");             break;         case '\t':             sb.append("\\t");             break;         default:             sb.append(c);         }     }     sb.append('\"');     return sb.toString();  }  

將 Number 表示為 JSON 就容易得多,利用 Java 的多態,我們可以處理 Integer,Long,Float 等多種 Number 格式:

  static String number2Json(Number number) {     return number.toString();  }  

Boolean 類型也可以直接通過 toString() 方法得到 JSON 的表示:

  static String boolean2Json(Boolean bool) {     return bool.toString();  }  

要將數組編碼為 JSON 格式,可以通過迴圈將每一個元素編碼出來:

  static String array2Json(Object[] array) {     if (array.length==0)         return "[]";     StringBuilder sb = new StringBuilder(array.length << 4);     sb.append('[');     for (Object o : array) {         sb.append(toJson(o));         sb.append(',');     }     // 將最後添加的 ',' 變為 ']':     sb.setCharAt(sb.length()-1, ']');     return sb.toString();  }  

最後,我們需要將 Map<String, Object> 編碼為 JSON 格式,因為 JavaScript 的 Object 實際上對應的是 Java 的 Map<String, Object> 。該方法如下:

  static String map2Json(Map<String, Object> map) {     if (map.isEmpty())         return "{}";     StringBuilder sb = new StringBuilder(map.size() << 4);     sb.append('{');     Set<String> keys = map.keySet();     for (String key : keys) {         Object value = map.get(key);         sb.append('\"');         sb.append(key);         sb.append('\"');         sb.append(':');         sb.append(toJson(value));         sb.append(',');     }     // 將最後的 ',' 變為 '}':     sb.setCharAt(sb.length()-1, '}');     return sb.toString();  }  

為了統一處理任意的 Java 對象,我們編寫一個入口方法 toJson(Object),能夠將任意的 Java 對象編碼為 JSON 格式:

  public static String toJson(Object o) {     if (o==null)         return "null";     if (o instanceof String)         return string2Json((String)o);     if (o instanceof Boolean)         return boolean2Json((Boolean)o);     if (o instanceof Number)         return number2Json((Number)o);     if (o instanceof Map)         return map2Json((Map<String, Object>)o);     if (o instanceof Object[])         return array2Json((Object[])o);     throw new RuntimeException("Unsupported type: " + o.getClass().getName());  }  

我們並未對 Java 對象作嚴格的檢查。不被支援的對象(例如 List)將直接拋出 RuntimeException 。此外,為了保證輸出的 JSON 是有效,Map<String, Object> 對象的 Key 也不能包含特殊字元。細心的讀者可能還會發現循環參考的對象會引發無限遞迴,例如,精心構造一個循環參考的 Map,就可以檢測到 StackOverflowException

  @Test(expected=StackOverflowError.class)  public void testRecurrsiveMap2Json() {     Map<String, Object> map = new HashMap<String, Object>();     map.put("key", map);     JsonUtil.map2Json(map);  }  

好在伺服器處理的 JSON 資料最終都應該轉化為簡單的 JavaScript 對象,因此,遞迴引用的可能性很小。

最後,通過 Servlet 或 MVC 架構輸出 JSON 時,需要設定正確的 MIME 類型(application/json)和字元編碼。假定伺服器使用 UTF-8 編碼,則可以使用以下代碼輸出編碼後的 JSON 文本:

  response.setContentType("application/json;charset=UTF-8");  response.setCharacterEncoding("UTF-8");  PrintWriter pw = response.getWriter();  pw.write(JsonUtil.toJson(obj));  pw.flush();  

小結

JSON 已經是 JavaScript 標準的一部分。目前,主流的瀏覽器對 JSON 支援都非常完善。應用 JSON,我們可以從 XML 的解析中擺脫出來,對那些應用 Ajax 的 Web 2.0 網站來說,JSON 確實是目前最靈活的輕量級方案。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.