JSON 入門指南

歡迎訪問: www.ptcms.cn

JSON 數據格式

-----------------------------------------------------

  •  Boolean :true false
  • js中的null 在 json裏標示爲 null
  • String 類型
  • js 中的數組對象
  • js中的 Object 相當於 Map 中的鍵值對 ,其實 鍵值在json 裏必須是 String 類型

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 確實是目前最靈活的輕量級方案。

發佈了36 篇原創文章 · 獲贊 1 · 訪問量 8215
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章