`
javaping2008
  • 浏览: 105859 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论
阅读更多

XML——这种用于表示客户端与服务器间数据交换有效负载的格式,几乎已经成了Web services的同义词。然而,由于AjaxREST技术的出现影响了应用程序架构,这迫使人们开始寻求`XML的替代品,如:JavaScript Object NotationJSON)。

JSON 作为一种更轻、更友好的 Web services客户端的格式(多采用浏览器的形式或访问 REST风格 Web服务的Ajax应用程序的形式)引起了 Web 服务供应商的注意。

XML的十字路口: 浏览器和 Ajax

  XML设计原理已经发布了将近十年。时至今日,这种标记语言已经在广阔的软件应用领域中占据了主导地位。从Java.NET等主流平台中的配 置和部署描述符到应用集成场景中更复杂的应用,XML与生俱来的语言无关性使之在软件架构师心目中占据着独特的地位。但即便最著名的XML权威也不得不承认:在某些环境中,XML的使用已经超出了它自身能力的极限。

  围绕Ajax原理构建的那些Web应用程序最能说明XML的生存能力,从这一点来看,一种新的有效负载格式的发展壮大也得益于XML。这种新的有效负载格式就是JavaScript Object Notation (JSON)。在探索这种新的标记语言的复杂性之前,首先来分析一下在这种独特的设计形式中,XML具有哪些局限性。

Ajax建立了一个用于从远程Web services发送和接收数据的独立信道,从而允许Web程序执行信道外(out-of-band)客户端/服务器调用。通俗地说,Ajax程序中的更 新和导航序列在典型的客户端/服务器环境之外完成,在后台(即信道外)接受到信息后,必须进行一次完整的屏幕刷新。

这些应用程序更新通常是通过REST风格(RESTfulWeb services获得的,一旦被用户的浏览器接收到,就需要整合到HTML页面的总体布局之中,这正是XML发挥强大力量的场合。尽管近年来,脚本语言支持和插件支持已使大多数主流浏览器的功能得到了强化,但许多编程任务依然难于开展,其中之一就是操纵或处理文本,这通常是使用DOM实现的。

采用DOM的复杂性源于其基于函数的根,这使得对数据树的简单修改或访问都需要进行无数次方法调用。此外,众所周知,DOM在各种浏览器中的实现细 节不尽相同,这一过程将带来极为复杂的编程模式,其跨浏览器兼容性出现问题的可能性极大。接下来的问题显而易见,那就是:如何使一种标记语言轻松集成到 HTML页面中以满足Ajax的要求?

  问题的答案就是:利用所有主流浏览器中的一种通用组件——JavaScript引擎。XML需要使用DOM之类的机制来访问数据并将数据整合到 布局之中,采用这种方法,我们不再使用像XML这样的格式来交付Ajax更新,而是采用一种更为简单直观的方式,采用JavaScript引擎自然匹配的格式——也就是JSON

 

既然已经明确了JSONXMLAjax之间的关系,下面将进一步探讨JSON背后的技术细节。

JSON剖析:优点和不足

  对于JSON,首先要明白JSONXML一样也是一种简单文本格式。相对于XML,它更加易读、更便于肉眼检查。在语法的层面上,JSON与 其他格式的区别是在于分隔数据的字符,JSON中的分隔符限于单引号、小括号、中括号、大括号、冒号和逗号。下图是一个JSON有效负载:

{"addressbook": {"name": "Mary Lebow",
    "address": {
        "street": "5 Main Street"
        "city": "San Diego, CA",
        "zip": 91912,
    },
    "phoneNumbers": [
        "619 332-3452",
        "664 223-4667"
    ]
 }
}

将上面的JSON有效负载用XML改写,如下:

<addressbook>
 <name>Mary Lebow</name>
 <address> 
    <street>5 Main Street</street>
    <city zip="91912"> San Diego, CA </city>
    <phoneNumbers>
      <phone>619 332-3452</phone>
      <phone>664 223-4667</phone>
    </phoneNumbers>
 </address>
</addressbook>

是不是很相似?但它们并不相同。下面将详细阐述采用JSON句法的优点和不足。

优点

  乍看上去,使用JSON的数据分隔符的优点可能并不那么明显,但存在一个根本性的缘由:它们简化了数据访问。使用这些数据分隔符时, JavaScript引擎对数据结构(如字符串、数组、对象)的内部表示恰好与这些符号相同。

  这将开创一条比DOM技术更为便捷的数据访问途径。下面列举几个JavaScript代码片段来说明这一过程,这些代码片段会访问先前的JSON代码片段中的信息:

  • 访问JSON中的名称: addressbook.name
  • 访问JSON中的地址: addressbook.address.street
  • 访问JSON中的电话号码第一位:addressbook.address.phoneNumbers[0]

  如果您具备DOM编程经验,就能很快地看出区别;

  JSON的另一个优点是它的非冗长性。在XML中,打开和关闭标记是必需的,这样才能满足标记的依从性;而在JSON中,所有这些要求只需通过 一个简单的括号即可满足。在包含有数以百计字段的数据交换中,传统的XML标记将会延长数据交换时间。目前还没有正式的研究表明JSONXML有更高的 线上传输效率;人们只是通过简单的字节数比较发现,对于等效的JSONXML有效负载,前者总是小于后者。至于它们之间的差距有多大,特别是在新的 XML压缩格式下它们的差距有多大,有待进一步的研究。

不足

  和许多好东西都具有两面性一样,JSON的非冗长性也不例外,为此JSON丢失了XML具有的一些特性。命名空间允许不同上下文中的相同的信息 段彼此混合,然而,显然在JSON中已经找不到了命名空间。JSONXML的另一个差别是属性的差异,由于JSON采用冒号赋值,这将导致当XML转化 为JSON时,在标识符(XML CDATA)与实际属性值之间很难区分谁应该被当作文本考虑。

  另外,JSON片段的创建和验证过程比一般的XML稍显复杂。从这一点来看,XML在开发工具方面领先于JSON

Web services生成JSON输出

  既然JSON的首要目标是来自浏览器的信道外请求,那么我们选择REST风格(RESTfulWeb服务来生成这些数据。除了用典型业务逻辑 探究Web服务之外,还将采用特定的API把本地Java结构转化为JSON格式。首先,下面的Java代码用来操纵Address对象:

SortedMap addressBook = new TreeMap();
Address maryLebow = new Address("5 Main Street","San Diego, CA",91912,"619-332-3452","664-223-4667"); 
addressBook.put("Mary Lebow",maryLebow);
 
Address amySmith = new Address("25 H Street","Los Angeles, CA",95212,"660-332-3452","541-223-4667"); 
addressBook.put("Sally May",amySmith);
 
Address johnKim = new Address("2343 Sugarland Drive","Houston, TX",55212,"554-332-3412","461-223-4667"); 
addressBook.put("John Kim",johnKim);
 
Address richardThorn = new Address("14 68th Street","New York, NY",,12452,"212-132-6182","161-923-4001"); 
addressBook.put("Richard Thorn",richardThorn);

  该Java结构在哪里生成并不重要(可能是在JSPServletEJBPOJO中生成),重要的是,在REST风格Web 服务中有权使用这些数据。如下示:

String result = new String();
String from = request.getParameter("from");
String to = request.getParameter("to");
 
try { 
     if(from != null && to != null) { 
           addressBook = addressBook.subMap(from,to);
     }
 
   JSONArray jsonAddressBook = new JSONArray();
 
   for (Iterator iter = addressBook.entrySet().iterator(); iter.hasNext();)  { 
 
      
     Map.Entry entry = (Map.Entry)iter.next();
     String key = (String)entry.getKey();
     Address addressValue = (Address)entry.getValue();
 
       JSONObject jsonResult = new JSONObject();
     jsonResult.put("name",key);
 
   
     String streetText = addressValue.getStreet();
     String cityText = addressValue.getCity();
     int zipText = addressValue.getZip();
     JSONObject jsonAddress = new JSONObject();
     jsonAddress.append("street",streetText);
     jsonAddress.append("city",cityText);
     jsonAddress.append("zip",zipText);
     jsonResult.put("address",jsonAddress);
     String telText = addressValue.getTel();
     String telTwoText = addressValue.getTelTwo();
     JSONArray jsonTelephones = new JSONArray();
     jsonTelephones.put(telText);
     jsonTelephones.put(telTwoText);
     jsonResult.put("phoneNumbers",jsonTelephones);
 
     jsonAddressBook.put(jsonResult);
   } 
 
     result = new JSONObject().put("addressbook",jsonAddressBook).toString();
 
  } catch (Exception e) {     
  }

  为了便于说明,我们已将这段代码将置入JSPrestservice.jsp)中。如果它真是一段程序,那么类似这样的代码也会出现在 servlethelper类中。 REST风格Web服务首先提取两个通过URL请求传递给它的输入参数,根据这些值过滤现有的地址簿以适应请求。过滤过地址簿后,即可开始循环检查 Java映射中的每个条目。

  您会注意到,在循环内部,json.org API被广泛用于将本地Java格式转化为JSON字符串。虽然仅使用了少量类(即JSONArrayJSONObject),但API提供的转换方法 相当广泛,甚至能将XML结构转换成JSON输出。但回到我们的Web服务,一旦循环遍历了所有条目,那么变量“result”会包含准备返回给请求方的地址簿的JSON同等部分。

  既然已经生成了JSON输出,下面来看看等式的另一边:浏览器应用程序中JSON有效负载的使用。

JSON有效负载的使用

  作为基于浏览器的客户端,我们的设计中大部分工作都是在HTMLJavaScript加上附加的JavaScript 框架下完成的。例如利用Prototype库轻松创建跨浏览器样式的Ajax调用。下面的清单包含了我们的应用程序的第一部分,以及相应的 JavaScript函数。

<html> 
<head> 
<title> JSON Address Book </title> 
<script type="text/javascript" src="prototype-1.4.0.js"></script> 
<script type="text/javascript"> 
// Method invoked when user changes letter range
function searchAddressBook()       {
 
  // Select values from HTML select lists
  var fromLetter = $F('fromLetter');
  var toLetter = = $F('toLetter');
 
  // Prepare parameters to send into REST web service
  var pars = 'from=' + fromLetter + '&to=' + toLetter;
  // Define REST web service URL 
  var url = 'restservice.jsp';
 
  // Make web service Ajax request via prototype helper, 
  // upon response, call showResponse method                 
  new Ajax.Request( url, { method: 'get', parameters: pars, 
                           onComplete: showResponse });
}
 
</script> 
</head>

  首先导入了prototype库,该库用于促进对REST风格Web服务的Ajax调用。接下来是searchAddressBook()函数,当用户修改其下所示的HTML选择列表时,将会触发此函数。该函数被触发后,用户将会获得HTML选择列表中已选中的选项,并将其放入两个用于过滤地 址簿的变量中,随后定义一个指向REST风格服务URL restservice.jsp的附加变量。

  此方法中还包括借助原型函数new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: showResponse }); 的实际Ajax Web服务调用;表明了对相关URL的一个请求,其请求参数包含在pars中;最后一旦Ajax请求终止,即执行showResponse()

  下面以showResponse()为例说明用于评估JSON有效负载并将其放入HTML主体布局环境中的的必要代码。

// Method invoked when page receives Ajax response from REST web service 
function showResponse(originalRequest)      {
   // Get JSON values 
   jsonRaw = originalRequest.responseText;
   // Eval JSON response into variable 
   jsonContent = eval("(" + jsonRaw + ")");
 
   // Create place holder for final response    
   finalResponse = "<b>" + jsonContent.addressbook.length + 
                   " matches found in range</b><br/>";
 
   // Loop over address book length.
   for (i = 0; i < jsonContent.addressbook.length; i++) {
        finalResponse += "<hr/>";
        finalResponse += "<i>Name:</i> " + jsonContent.addressbook[i].name + "<br/>";          
        finalResponse += "<i>Address:</i> " + jsonContent.addressbook[i].address.street + " -- " + 
                          jsonContent.addressbook[i].address.city + "," +           
                          jsonContent.addressbook[i].address.zip + ".<br/>";          
        finalResponse += "<i>Telephone numbers:</i> " + jsonContent.addressbook[i].phoneNumbers[0] + " & " + 
        jsonContent.addressbook[i].phoneNumbers[1] + ".";          
   }
 
   // Place formatted finalResponse in div element
   document.getElementById("addressBookResults").innerHTML = finalResponse;
 }

  此方法的输入参数是REST风格Web服务在调用时返回的响应。既然预先已经知道需要处理JSON字符串,那么可以利用JavaScript eval()函数,将这个JSON字符串放入内存,并允许数据访问,正是这样的简便性促使开发人员使用JSON。完全不需要进行解析,一个简单的eval ()即可得到JavaScript结构,我们可以像操纵其他任何JavaScript结构一样地去操纵它。

  一旦JSON响应经过eval处理,将创建一个JavaScript循环来提取每个地址条目,并将各个匹配项放入一个名为 finalResponse的容器变量中。而这个容器变量本身包含所有必要的格式,用于在页面布局中显示最终地址簿。循环结束时,匹配项也通过 document.getElementById("addressBookResults").innerHTML放置完毕。

  最后,为了保持完整,页面的实际布局由这些代码组成:

<body> 
<h4 style="text-align:left">Request address book matches:</h4>
<table style="text-align:left" cellpadding="15"><tr><td valign="top">From:<br/>
<select id="fromLetter" size="15" onchange="searchAddressBook()">
         <option>A</option>
         ...
         <option>Z</option>
</select>
</td><td valign="top">To:<br/>
<select id="toLetter" size="15" onchange="searchAddressBook()">
         <option>A</option>
         ...
         <option>Z</option>
</select>
</td><td valign="top">
<h5> Results </h5> 
<div style="text-align:left" id="addressBookResults">Please select range</div>
</td></tr>
</table>
</body> 

  上面的代码清单中最值得一提的是HTML选择列表,因为修改触发器Java程序需要调用信道外Ajax请求。其次,<div>元素 就是放置格式化后的JSON响应的地方。                                         在软件设计中编程语言的选择一样,JSON的选择与否取决于您自身的需求, 如果Web services使用者将在传统、功能完备的编程环境(如Java .NETPHPRuby等)中创建,那么完全可以不使用JSON。给定大多数编程语言环境的无限制能力可提供完整的配置控制权(更不必说对定制库、分析器或helper类的访问),那么JSONXML及其他Web services有效载荷之间的差别可以忽略不计。

  反之,如果Web services使用者被限制在浏览器环境之外,那么JSON是值得认真考虑的对象。在浏览器中使用Web services并非兴趣使然,而是实际业务需求。如果这时需要一个加载数据时不会出现延迟/刷新的漂亮的Web 2.0界面, 就不得不在浏览器中嵌入AjaxWeb services技术,这个也是我们二年需要学习的一门技术.

  XML相比,JSON是未来Web软件发展的一个趋势.也希望大家能够掌握.

分享到:
评论

相关推荐

    ZUI2_JSON2_/UI2/CL_JSON_ui2/cl_json_abap_Ui2_cl_json_zui2_json_源

    标题中的"ZUI2_JSON2_/UI2/CL_JSON_ui2/cl_json_abap_Ui2_cl_json_zui2_json_源"可能指的是一个与ZUI2相关的项目,它利用了ABAP类/UI2/CL_JSON来解析和生成JSON数据。描述中提到,我们需要用到这个类来将JSON格式的...

    json2.js 亲测可用

    JSON2.js是一个JavaScript库,由Douglas Crockford开发,主要目的是为了在旧版本的JavaScript引擎中提供完整的JSON支持。 在JavaScript中,JSON对象是原生支持的,但在一些较老的浏览器或环境中,如IE6和IE7,它们...

    javascript json数据解析工具json2.js

    JSON2.js是由Douglas Crockford开发的一个JavaScript库,专门用于处理JSON数据,尤其在老版本的浏览器中,这些浏览器可能不支持原生的JSON解析和序列化功能。 在JavaScript中,JSON主要用于对象与字符串之间的转换...

    json+json2

    在提到“json+json2”时,我们可以理解这是关于JSON的两个不同版本的JavaScript实现。在提供的文件列表中,"json2.js"和"json.js"可能分别是这两个版本的实现。 首先,让我们来看看"json.js"。这可能是早期的一个...

    jquery.json2xml.js和jquery.xml2json.js

    在jQuery的基础上,`jquery.json2xml.js` 和 `jquery.xml2json.js` 这两个脚本提供了方便的方法来在JSON和XML之间进行转换,从而让开发者无需深入了解这两种格式的复杂性,就能轻松地在它们之间进行数据互换。...

    格式转换工具json2bin

    "json2bin"是一个专门用于将JSON数据转换为二进制格式的工具。它能够将JSON对象转换成更紧凑的二进制表示,从而节省存储空间和提高处理速度。在软件开发过程中,这样的工具非常有用,尤其是在处理大量结构化数据时。...

    json2.js 字符串转转json对象工具

    `json2-debug.js`通常是开发版本,包含了更多的调试信息,而`json2.js`则是优化后的版本,通常用于生产环境,体积更小,运行速度更快。在实际项目中,你应该根据开发和部署的需求选择使用哪一个版本。 总的来说,...

    json2-min.js(亲测可用)

    `json2-min.js` 文件是一个针对JSON的JavaScript库,主要功能是为那些不支持原生JSON的旧版浏览器提供JSON的解析和序列化功能。 在JavaScript中,JSON主要用于数据传输,特别是在与服务器进行AJAX通信时。原生的...

    json2.js json.js

    JSON2.js是一个JavaScript库,由Douglas Crockford开发,主要目的是为了解决在旧版本的JavaScript引擎中对JSON支持不足的问题。 在JavaScript中,原生的JSON对象在ECMAScript 5版本(ES5)及更新的环境中被内置,...

    json2.js包

    `json2.js`是一个JavaScript库,由 Douglas Crockford 创建,主要用于在不支持JSON的旧版浏览器中实现JSON的解析和序列化。 ### JSON2.js 的主要功能 1. **JSON解析**:`json2.js` 提供了一个`JSON.parse()`方法,...

    json.js,json2.js 和 json.jar 下载

    **json.js** 和 **json2.js** 是两个JavaScript库,用于在浏览器环境中处理JSON数据。`json.js`可能是早期的一个JSON处理库,它提供了JSON的解析(`parse()`)和字符串化(`stringify()`)功能,使得在不支持JSON的...

    Xml2Json and Json2Xml

    在提供的文件中,`xml2json.js`和`json2xml.js`可能包含了这些转换功能的具体实现。`xmljson_test.htm`可能是一个测试页面,用于展示这两种转换的实际效果和验证代码的正确性。通过阅读和理解这些源代码,我们可以更...

    json2.js压缩包

    《json2.js:JavaScript中的JSON解析与序列化》 在Web开发中,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于JavaScript的一个子集,易于人阅读和编写,同时也易于机器解析和生成。JSON2....

    json2.js下载

    `json2.js` 是一个JavaScript库,由Douglas Crockford 创建,主要用于在那些不支持原生JSON解析和序列化的老版本浏览器上提供JSON功能。 在JavaScript中,JSON是一个内置对象,提供了`parse()`和`stringify()`两个...

    json2的js文件

    JSON2.js 是一个JavaScript库,由Douglas Crockford 创建,主要目的是为了解决旧版本的JavaScript(特别是IE6和IE7)对JSON不支持的问题。在这些旧版浏览器中,原生的JSON对象不被支持,因此需要JSON2.js这样的库来...

    前端json2的js包。

    JSON2.js是针对旧版本JavaScript的一个库,主要目的是为了在那些不支持原生JSON的浏览器中提供JSON的解析和序列化功能。 JSON2.js的核心功能包括两个部分:`JSON.stringify()`和`JSON.parse()`。这两个方法在现代...

    json/json2.js两个版本

    在您提到的“json/json2.js”中,我们有两个不同版本的JSON实现。 `json.js`可能是早期的一个JSON处理库,可能包含了对JSON字符串的解析(parse)和字符串化(stringify)功能。在JavaScript的早期版本,尤其是那些...

    json2 使用方法

    `json2.js`是一个JavaScript库,由Douglas Crockford编写,它为那些不支持JSON.parse()和JSON.stringify()的旧版浏览器提供了JSON解析和序列化功能。这篇博文将详细介绍如何使用`json2.js`。 在JavaScript中,JSON...

    jsp使用JSON.stringify()引用的json2.js

    jsp使用JSON.stringify()引用的json2.js

    json2.js文件下载

    将JavaScript对象类型的参数通过JSON.stringify转换成字符串传递时,IE6、7、8会报:“JSON”未定义 的错误。可以通过在html文件的head头内引入json2.js文件来解决:

Global site tag (gtag.js) - Google Analytics