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 阿蜜果 阅读(4452) 评论(0)  编辑  收藏 所属分类: Ajax

只有注册用户登录后才能发表评论。


网站导航:
 
<2010年9月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

      生活将我们磨圆,是为了让我们滚得更远——“圆”来如此。
      我的作品:
      玩转Axure RP  (2015年12月出版)
      

      Power Designer系统分析与建模实战  (2015年7月出版)
      
     Struts2+Hibernate3+Spring2   (2010年5月出版)
     

留言簿(262)

随笔分类

随笔档案

文章分类

相册

关注blog

积分与排名

  • 积分 - 2285128
  • 排名 - 3

最新评论

阅读排行榜

评论排行榜