posts - 297,  comments - 1618,  trackbacks - 0
           

          蜜果私塾:JSON知識總結入門篇

          記錄人:阿蜜果

          日期:2010-9-25

          1.     何謂JSON

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

          JSON具有如下具體形式:

          1)JSON是一個無序的“名稱/值”對的集合。一個對象以“{”開始,“}”結束,每個名稱后跟一個“:”號,“名稱/值”對之間使用“,”分隔;

          2)數組是值(value)的有序集合。一個數組以“[”(左中括號)開始,“]”(右中括號)結束。值之間使用“,”(逗號)分隔;

          3)值(value)可以是雙引號括起來的字符串(string)、數值(number)truefalse null、對象(object)或者數組(array)。這些結構可以嵌套;

          4)字符串(string)是由雙引號包圍的任意數量Unicode字符的集合,使用反斜線轉義。一個字符(character)即一個單獨的字符串(character string)。字符串(string)與C或者Java的字符串非常相似;

          5)數值(number)也與C或者Java的數值非常相似。除去未曾使用的八進制與十六進制格式。除去一些編碼細節。

          2.     JSONXML的比較

          從如下部分進行比較:

          1)可讀性JSONXML的可讀性稍微差點,相比來說XML更結構化。一邊是簡易的語法,一邊是規范的標簽形式;

          2) 可擴展性XML天生有很好的擴展性,JSON當然也有,沒有什么是XML能擴展,JSON不能的。不過JSONJavascript主場作戰,可以存儲Javascript復合對象,有著xml不可比擬的優勢;

          3) 編碼難度XML有豐富的編碼工具,比如Dom4jJDom等,JSON也有提供的工具。無工具的情況下,相信熟練的開發人員一樣能很快的寫出想要的xml文檔和JSON字符串,不過,xml文檔要多很多結構上的字符;

          4)解碼難度

          XML的解析方式有兩種:一是通過文檔模型解析,也就是通過父標簽索引出一組標記。例如:xmlData.getElementsByTagName("tagName"),但是這樣是要在預先知道文檔結構的情況下使用,無法進行通用的封裝。

          另外一種方法是遍歷節點(document 以及 childNodes)。這個可以通過遞歸來實現,不過解析出來的數據仍舊是形式各異,往往也不能滿足預先的要求。

          凡是這樣可擴展的結構數據解析起來一定都很困難。

          如果預先知道JSON結構的情況下,使用JSON非常簡單。純粹的前臺開發人員,一定會非常喜歡JSON。但是如果你是一個應用開發人員,就不是那么喜歡了,畢竟xml才是真正的結構化標記語言,用于進行數據傳遞。而如果不知道JSON的結構而去解析JSON的話,那就非常費勁。

          Javascript地盤內,JSON畢竟是主場作戰,其優勢當然要遠遠優越于xml。如果JSON中存儲Javascript復合對象,而且不知道其結構的話,我相信很多程序員也一樣是哭著解析JSON的。

          3.     簡單實例

          3.1從文本中取得JSON字符串

          3.1.1 功能描述

          在下面的實例中json.html通過ajax獲得json.txt中的JSON字符串的內容,并在json.html對結果進行解析后進行展示。

          3.1.2 JSON字符串文件:json.txt

          如果json.txt文件中的json字符串為:

          {
          "programmers": [
              
          "firstName""阿蜜果""lastName":"McLaughlin""email""brett@newInstance.com" },
              
          "firstName""范范""lastName":"Hunter""email""jason@servlets.com" },
              
          "firstName""高子""lastName":"Harold""email""elharo@macfaq.com" }
             ],
          "authors": [
              
          "firstName""安安""lastName""Asimov""genre""science fiction" },
          "firstName""Tad""lastName""Williams""genre""fantasy" },
          "firstName""Frank""lastName""Peretti""genre""christian fiction" }
             ],
          "musicians": [
              
          "firstName""茂茂""lastName""Clapton""instrument""guitar" },
          "firstName""Sergei""lastName""Rachmaninoff""instrument""piano" }
             ]
          }

          例如如果想獲得第一個程序員的firstName,可通過如下語句:

          var result = xmlHttp.responseText;
          var json 
          = eval("(" + result + ")");
          alert(json.programmers[
          0].firstName);

          第二個authorsgenre可通過如下語句獲得:

          json.authors[0].genre

          3.1.2 JSON字符串讀取和解析文件:json.html

          將如上的json.txt保存為UTF-8的文件,編輯json.html文件,內容參考如下:

          <html>
              
          <head>
                  
          <title>JsonTest</title>
                  
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                  
          <script type="text/javascript">
                  
          var xmlHttp;
                  
          function createXMLHttpRequest()
                  
          {
                      
          if(window.ActiveXObject)
                      
          {
                          xmlHttp 
          = new ActiveXObject("Microsoft.XMLHTTP");
                      }

                      
          else if(window.XMLHttpRequest)
                      
          {
                          xmlHttp 
          = new XMLHttpRequest();
                      }

                  }


                  
          function startRequest()
                  
          {
                      createXMLHttpRequest();
                      
          try
                      
          {
                          xmlHttp.onreadystatechange 
          = handleStateChange;
                          xmlHttp.open(
          "GET""json.txt"true);
                          xmlHttp.send(
          null);
                      }

                      
          catch(exception)
                      
          {
                          alert(
          "xmlHttp Fail");
                      }

                  }


                  
          function handleStateChange()
                  
          {    
                      
          if(xmlHttp.readyState == 4)
                      
          {        
                          
          if (xmlHttp.status == 200 || xmlHttp.status == 0)
                          
          {
                              
          var result = xmlHttp.responseText;
                              
          var json = eval("(" + result + ")");
                              alert(json.programmers[
          0].firstName + ',' + json.programmers[0].lastName + ',' + json.programmers[0].email);
                              alert(json.programmers[
          1].firstName + ',' + json.programmers[1].lastName + ',' + json.programmers[1].email);
                              alert(json.programmers[
          2].firstName + ',' + json.programmers[2].lastName + ',' + json.programmers[2].email);

                              alert(json.authors[
          0].firstName + ',' + json.authors[0].lastName + ',' + json.authors[0].genre);
                              alert(json.authors[
          1].firstName + ',' + json.authors[1].lastName + ',' + json.authors[1].genre);
                              alert(json.authors[
          2].firstName + ',' + json.authors[2].lastName + ',' + json.authors[2].genre);

                              alert(json.musicians[
          0].firstName + ',' + json.musicians[0].lastName + ',' + json.musicians[0].instrument);
                              alert(json.musicians[
          1].firstName + ',' + json.musicians[1].lastName + ',' + json.musicians[1].instrument);
                          }

                      }

                  }

                  
          </script>
              
          </head>
              
          <body>
                  
          <div>
                      
          <input type="button" value="JSON Test" onclick="startRequest();" />
                  
          </div>
              
          </body>
          </html>

          ajax的回調函數handleStateChange中,讀者可對照json.txt文件重點關注下json字符串的取值方法。

          3.2Java對象轉換為JSON字符串

          3.2.1        功能描述

             在該實例中,講述如何將Java構造的復雜對象轉換為JSON字符串,Pagination對象中包含int類型的pageNo屬性,還包括List列表類型的resultList中包括的又是Book類型的對象,Book對象包括簡單類型的屬性idname,也包括List對象authors,表示該書的多個作者信息。authors列表的對象包含idname屬性。

             我們構造一個Pagination類型的分頁對象,它包含兩本書Book對象,分別為《人生若只如初見》和《海邊的卡夫卡》,并設置了它們的作者等信息。

          3.2.2        建立工程,并將包引入

             在Eclipse中建立一個jsonStudyJava工程或Java Web工程,在src目錄下建立com.amigo.json包,用來放置本示例的Java代碼。

             另外轉換時需要用到一些包,需要將其放到lib目錄下,所需的包如下圖所示:

            

             commons系列的包,可在網站:http://www.docjar.com/上面搜索下載,其它包可下載網站如下:

             json-lib-2.2-jdk15.jarhttp://json-lib.sourceforge.net/

             ezmorph.jar      http://ezmorph.sourceforge.net/

             morph-1.0.1.jar   http://morph.sourceforge.net/

          3.2.3        JavaBean對象

             Author類:

          package com.amigo.json;

          public class Author {
              
          private String id;

              
          private String name;

              
          // 省略getter/setter方法
          }

             Book類:

          package com.amigo.json;

          import java.util.List;

          public class Book {
              
          private String id;

              
          private String name;

              
          private List<Author> authors;

              
          // 省略getter/setter方法
          }

             Pagination類:

          package com.amigo.json;

          import java.util.List;

          public class Pagination {
              
          private int pageNo;

              
          private List<Object> results;

              
          // 省略getter/setter方法
          }

          3.2.4        測試類

             JsonTest測試類:

          package com.amigo.json;

          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
          import net.sf.json.JSONArray; 
          import net.sf.json.JSONObject;

          public class JsonTest {
              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) 
                  
          // 當是對象的時候
                  Author author = new Author();
                  author.setId(
          "1");
                  author.setName(
          "張三"); 
                  JSONObject jsonObject 
          = JSONObject.fromObject(author); 
                  System.out.println(jsonObject);

                  
          // 當是數組或list的時候
                  Author[] authors = new Author[5]; 
                  List
          <Author> authorsList = new ArrayList<Author>(); 
                  
          for (int i = 0; i < authors.length; i++
                      authors[i] 
          = new Author(); 
                      authors[i].setId(String.valueOf(i 
          + 1)); 
                      authors[i].setName(
          "張三" + (i + 1));
                      
          // 添加到list
                      authorsList.add(authors[i]); 
                  }
           
                  JSONArray jsonArray 
          = JSONArray.fromObject(authorsList); 
                  System.out.println(jsonArray);

                  jsonArray 
          = JSONArray.fromObject(authors);
                  System.out.println(jsonArray);

                  
          // 復雜結構構造
                  Map<String,Object> map = new HashMap<String,Object>(); 
                  Pagination pagination 
          = new Pagination();
                  pagination.setPageNo(
          1);
                  pagination.setResults(
          new ArrayList<Object>());

                  
          // 構造第一個book的信息
                  Book book = new Book();
                  book.setId(
          "1");
                  book.setName(
          "人生若只如初見");
                  book.setAuthors(
          new ArrayList<Author>());
                  pagination.getResults().add(book);

                  author 
          = new Author();
                  author.setId(
          "1");
                  author.setName(
          "張三");
                  book.getAuthors().add(author);
                  
                  author 
          = new Author();
                  author.setId(
          "2");
                  author.setName(
          "李四");
                  book.getAuthors().add(author);

                  
          // 構造第二個book的信息
                  Book book2 = new Book();
                  book2.setId(
          "2");
                  book2.setName(
          "海邊的卡夫卡");
                  book2.setAuthors(
          new ArrayList<Author>());
                  author 
          = new Author();
                  author.setId(
          "1");
                  author.setName(
          "村上春樹");
                  book2.getAuthors().add(author);
                  pagination.getResults().add(book2);

                  map.put(
          "page", pagination);

                  JSONObject jsonObjectFromMap 
          = JSONObject.fromObject(map); 
                  System.out.println(jsonObjectFromMap);
              }

          }

             如上測試類展示了如何使用所引包里面的方法來將Java簡單對象、列表、數組和復雜的Map對象轉換為JSON字符串的方法。

          3.2.5        運行結果

             運行JsonText.java,運行結果如下:

          {"id":"1","name":"張三"}

          [
          {"id":"1","name":"張三1"},{"id":"2","name":"張三2"},{"id":"3","name":"張三3"},{"id":"4","name":"張三4"},{"id":"5","name":"張三5"}]

          [
          {"id":"1","name":"張三1"},{"id":"2","name":"張三2"},{"id":"3","name":"張三3"},{"id":"4","name":"張三4"},{"id":"5","name":"張三5"}]

          {"page":{"pageNo":1,"results":[{"authors":[{"id":"1","name":"張三"},{"id":"2","name":"李四"}],"id":"1","name":"人生若只如初見"},{"authors":[{"id":"1","name":"村上春樹"}],"id":"2","name":"海邊的卡夫卡"}]}}

             該實例Map復合結構的格式化的JSON字符串為:

          {
          "page":
              
          {"pageNo":1,
               
          "results":
                  [
          {
                   
          "authors":
                        [
                         
          {"id":"1""name":"張三"},
                         
          {"id":"2""name":"李四"}
                        ],
                   
          "id":"1",
                   
          "name":"人生若只如初見"
                   }
          ,
                   
          {
                   
          "authors":
                         [
                          
          {"id":"1","name":"村上春樹"}
                         ],
                    
          "id":"2",
                    
          "name":"海邊的卡夫卡"
                    }
          ]
               }

          }

            有興趣的讀者可將該字符串拷貝到上面實例的json.txt文件中,并稍微修改下json.html對內容進行輸出。

          4.     常見問題

          4.1中文亂碼問題說明

             在3.1的實例中,為了避免中文亂碼問題,需要注意以下兩點:

          1)json.html中添加如下一句:

          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

          2)使用UE等保存json.txt文件時,需要將其保存為UTF-8模式。

          4.2java.lang.NoClassDefFoundError:net/sf/ezmorph/Morpher異常

          3.2的實例中,當筆者沒有將ezmorph.jarmorph-1.0.1.jar包導入時,雖然類都沒有報錯,但是運行時拋出java.lang.NoClassDefFoundError:net/sf/ezmorph/Morpher異常,如果讀者也出現該異常,需要將這沒有加入的包加入到工程中。

          5.     參考文檔

          JSON_百度百科》:http://baike.baidu.com/view/136475.htm

          《一個處理JSON的例子,帶演示》:http://bbs.blueidea.com/thread-2790525-1-1.html

          JSON實例》:http://hi.baidu.com/northarcher/blog/item/05d7fa1fca9c9ec3a786699f.html

          JSON中,java.lang.NoClassDefFoundError:net/sf/ezmorph/Morpher異常解決》:http://minner.javaeye.com/blog/428802

          posted on 2010-09-25 15:23 阿蜜果 閱讀(4472) 評論(0)  編輯  收藏 所屬分類: Ajax
          <2010年9月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

                生活將我們磨圓,是為了讓我們滾得更遠——“圓”來如此。
                我的作品:
                玩轉Axure RP  (2015年12月出版)
                

                Power Designer系統分析與建模實戰  (2015年7月出版)
                
               Struts2+Hibernate3+Spring2   (2010年5月出版)
               

          留言簿(263)

          隨筆分類

          隨筆檔案

          文章分類

          相冊

          關注blog

          積分與排名

          • 積分 - 2296322
          • 排名 - 3

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 成安县| 梁平县| 手游| 保康县| 大冶市| 金乡县| 凤凰县| 乃东县| 台南县| 江永县| 玉屏| 连云港市| 沂水县| 江北区| 桂平市| 东丰县| 涿州市| 托克逊县| 六盘水市| 安顺市| 天峨县| 望江县| 南郑县| 蓬安县| 新蔡县| 辉南县| 林周县| 东至县| 盐源县| 广西| 常宁市| 中超| 四川省| 合水县| 开原市| 衡东县| 枣阳市| 崇仁县| 洞口县| 桂林市| 平罗县|