p.height=metricToImperial(p.height); 

}print (x);这里是输出内">

AJAX及使用E4X编写Web服务脚本(2)

80酷酷网    80kuku.com

  ajax|web|web服务|脚本

for each (var p in x.person) {

if (p.height.measure=="metric")

p.height=metricToImperial(p.height); 

}

print (x);

这里是输出内容:

<people>

<person gender="male">

<name>Ant</name>

<hair>Shaggy</hair>

<eyes>Blue</eyes>

<height measure="imperial">

<feet>5</feet>

<inches>11</inches>

</height>

</person>

<person gender="male">

<name>Paul</name>

<hair>Spiky</hair>

<eyes>Grey</eyes>

<height measure="imperial">

<feet>5</feet>

<inches>12</inches>

</height>

</person>

</people>

E4X 中的 XML 命名空间(Namespace)

如果您是一名 XML 高手,那么此时您可能想知道如何使用该语法来管理 XML 命名空间。这里有三种方式来实现该操作:

首先,您可以使用内嵌的 XML 语法:

var soapMsg = <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"/>;

print(soapMsg.namespace());

http://www.w3.org/2003/05/soap-envelope

第二个方法是在创建元素之前设置缺省的 XML 命名空间:

default xml namespace = new Namespace("http://www.w3.org/2003/05/soap-envelope");

您可以将它设置为空字符串,以便对该缺省的命名空间进行重新设置,例如:

default xml namespace = ""

最后一种方法是使用 :: 运算符

var f = new Namespace("http://fremantle.org");

soapMsg.Body.f::GetStockQuote="IBM";

print(soapMsg);

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">

<s:Body>

<frem:GetStockQuote xmlns:frem="http://fremantle.org">

IBM

</frem:GetStockQuote>

</s:Body>

</s:Envelope>

XML 元素排序

E4X 所具有的一个明显的优点是它完全支持 XML,包括排序功能。许多从 XML 文档到相应编程语言对象的直接映射仅仅支持符合常规对象语义的 XML 语义子集——因此就失去了不仅能够表示对象而且还表示文档的功能。但是对本文来说,它是不合适的,只要简单查看一下该规范就可以看出,E4X XML 对象具有的内置功能能够对 XML 元素进行细致准确的排序。

在 XML 中使用 Javascript 表达式

在转向 Web 服务之前,我们向您介绍的最后一个内容——使用大括号“{}”以上我们介绍了“内嵌的”XML。E4X 也允许您重新进入 JavaScript 环境,并且可以包括了计算后的表达式值。例如:

var num = 36;

var p = <paul><age>{num}</age></paul>

print(p);

<paul>

<age>36</age>

</paul>

到目前为止,我们已经介绍了 E4X 的基础知识,下面我们就可以使用这些基本知识进行以下操作。

使用 E4X 来调用 Web 服务

本节中,我们将描述如何在以下两个环境中使用 E4X:

1. 使用 XMLHttpRequest 的 Mozilla 1.8

2. Java/Rhino

您可以很容易地在浏览器中使用 E4X 来调用 Web 服务。但是这里存在问题!到目前为止,唯一的支持 E4X 的浏览器是 Mozilla 1.8 的专业版。不过我们并没有将其作为一种可移植的跨浏览器的解决方案来推荐,以下的实例演示了 E4X 如何以一种简单的方式来调用 Web 服务。在下一节中,我们将查看运行在 Rhino JavaScript 引擎中的另一种方法。

AJAX

该样本实例显示了向 SOAP 服务器发送和接收 SOAP 消息的浏览器。为了实现该操作,我们通过 XMLHttpRequest 对象来使用 E4X 。这个对象非常的有用,而且 Mozilla 和 Internet Explorer 浏览器都支持它,它允许运行在浏览器内部的脚本语言在后台中生成 HTTP 请求。实际上,这就是为什么 Google 的 GMail 能做到任何事情的原因。这种架构最近被命为 Asynchronous JavaScript+XML(AJAX)。

从根本上来说,AJAX 的目的是要通过一种比标准 HTML 和 HTTP 的“页面”模型更为灵活的方式与服务器进行交互,以此来提高 Web 页面的响应能力和可用性。有关这方面一个很好的样本是 Google Maps beta,它明显地比以前的映射 Web 站点更具交互性。

令人鼓舞的是,根据新闻报道,结合了 E4X 的 AJAX 的性能更优!我们将向您展示浏览器应用的两种版本。第一个版本演示了交互操作,而第二个版本隐藏了 Web 页面上的按钮和内部的工作过程,以此来展示交互性和异步性。

浏览器的安全性

为了演示浏览器的安全性,我们使用了 xmethods.net 上可用的标准 Web 服务。但是,这里还存在一个问题,因为一般来说,浏览器的安全性规则不允许脚本程序或者 Java applet 程序创建网络连接,除非是与生成该页面的服务器建立网络连接。否则,您需要有一个监控页面,它将您的按键操作“复制”到另外一个服务器。

但是您可以避开这种操作。为实现该操作,您需要进行两步。首先,您必须启用 Mozilla 配置中的用于脚本程序的升级特权。(假定您已经下载并安装了 Mozilla 1.8 beta)。

在该浏览器的地址栏中输入 about:config,然后将 signed.applets.codebase_principal_support 的值从 false 更新为 true。(出于安全性考虑,请记得在完成全部操作后设回原值。)

然后在脚本程序中,您可以请求使用升级特权。当该脚本语言运行时,将会提示用户使用这些特权。代码行为:

netscape.security.PrivilegeManager.enablePrivilege( "UniversalXPConnect UniversalBrowserAccess");

其它的选择就是将服务和 Web 页面部署到诸如 IBM® WebSphere® Application Server 或者 Tomcat 之类的 Web 应用程序服务器中。例如,这种方式适用 Apache Axis 和 Axis 自带的缺省股票报价机样本实例。
股票报价客户端样本 


该脚本程序属于 stockclient.html 的一部分。如果您从本文下载了 ws-ajax1code.zip 文件,将其中的 zip 内容解压,然后使用 Mozilla 打开 stockclient.html,您将会看到如下内容:

图 1. Mozilla 中的 stockclient.html

为了对其进行验证,首先单击 Update URL。该操作通过使用 XMLHttpRequest 对象从 http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl(或者您在 WSDL 框中键入的任意 URL)获取 WSDL 文件,然后使用 E4X 从那里获取端口地址 URL。现在单击 Send,您将会看到 SOAP 请求被填写了。一两秒钟之后,此 SOAP 响应应该同结果字段一起被更新。我们查看一下这些代码。

股票报价客户端的脚本程序

该脚本程序带着对 IBM 的股票价格的 request 调用指定的URL。如果您正在使用 Axis 服务器,那么我们建议使用股票行情自动收录机符号 XXX,这是一种特殊的符号——部署的服务将总是返回一个固定的响应用于该收录机,而不是产生 Web 请求来得到真正的股票价格——因此使用该符号进行测试会好些。

您必须完成的第一个操作就是定义您希望使用的 E4X:

<script type="text/javascript;e4x=1">

当您按下 Send 按钮时,该脚本程序显示如下:

    var s = new Namespace(

"s",

"http://schemas.xmlsoap.org/soap/envelope/");

var envelope = <s:Envelope xmlns:s={s}/>;

envelope.s::Body="";

var body = envelope.s::Body;

该操作对任何的 SOAP 请求都是通用的它只是简单地创建了一个 SOAP 信封,而没有包括任何消息体该操作的一个等价实现方式如下所示:

var envelope =

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

<s:Body/>

</s:Envelope>

但是,前面的代码会容易些,而且也为您提供了指向主体元素的指针

下一步是要创建消息的主体:

   var x = new Namespace("x","urn:xmltoday-delayed-quotes");

body.x::getQuote = <x:getQuote xmlns:x={x}/>;

最后,你必须添加正确的符号:

   var symbol = document.getElementById("symbol").value; 

var getQuote = body.x::getQuote;

getQuote.symbol=symbol;

现在您已经有了一个完全成形的 SOAP 请求消息如果您想要测试该消息信封,那么需要按照以下操作:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

<s:Body>

<x:getQuote xmlns:x="urn:xmethods-delayed-quotes">

<symbol>XXX</symbol>

</x:getQuote>

</s:Body>

</s:Envelope>

为了发送它,你必须使用 XMLHTTPRequest 对象我们创建了一个简单的辅助函数,以支持使用 XMLHttpRequest 对象来调用使用 E4X 的服务此 execService 函数不仅支持异步方式而且也支持同步方式

function execService(url, xml, callback) {

var xmlhttp = new XMLHttpRequest();

var async=false;

if (arguments.length==3) async=true;

xmlhttp.open("POST", url, async);

xmlhttp.setRequestHeader("SOAPAction", "\"\"")

xmlhttp.setRequestHeader("Content-Type", "text/xml")

if (async) {

var f = function() {

if (xmlhttp.readyState==4) {

callback(new XML(xmlhttp.responseText));

}

}

      xmlhttp.onreadystatechange = f;

}

xmlhttp.send(xml.toString());

if (!async) return new XML(xmlhttp.responseText);

}

下面我们来详细地看看这些代码首先,这些代码支持两种调用方式您可以使用其中一种:

     XML execService(String url, XML envelope);或者void execService(String url, XML envelope, function callback);

在这种情况下,回调函数应该是 void callback(XML x)

于是您可以使用该函数直接调用 XML 服务,并且等待响应,或者您也可以传送一个函数,使用 XML 响应消息调用该函数

该函数基于参数的数量来决定它是异步还是同步(3 是异步),然后简单地使用 XMLHttpRequest 对象以 POST 请求方式来把 XML 消息放到 HTTP 请求信息,并把请求发送到指定的 URL



分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: