Chinaunix首页 | 论坛 | 博客
  • 博客访问: 303321
  • 博文数量: 153
  • 博客积分: 3347
  • 博客等级: 中校
  • 技术积分: 1556
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-30 17:50
文章分类

全部博文(153)

文章存档

2013年(7)

2012年(21)

2011年(46)

2010年(16)

2009年(63)

我的朋友

分类: 系统运维

2010-01-05 11:25:59

2006 年 5 月 25 日

使用 Asynchronous JavaScript and XML (Ajax) 设计模式实现基于 Web 浏览器的 SOAP Web 服务。在本系列的第 1 部分“使用 Ajax 调用 SOAP Web 服务,第 1 部分” 中,作者引入了一个简单的用于调用 SOAP Web 服务的基于 Web 浏览器的 JavaScript 库。在接下来的讨论中,作者将实现对 Web 服务寻址语言 (Web Services Addressing Language) 和 Web 服务资源框架 (Web Services Addressing Language) 规范的支持,以便扩展 JavaScript 库的功能。

请访问 Ajax 技术资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何新信息都能在这里找到。

在 本系列的第 1 部分,我介绍了一个跨浏览器的 JavaScript 库,其中提供了一个简单的 SOAP Web 服务客户机,该客户机可以发出采用 RRC 编码和文档-文本样式的请求。该客户机包含对请求和响应处理程序、自定义 XML 序列化器/反序列化器以及 SOAP Header 的支持;所有这些支持都将在这个 WS-Addressing 和 WS-ResourceFramework 实现中用到。

ws.js (在第 1 部分中引入的)中定义的主要对象包括:

  1. WS.Call:包装 XMLHttpRequest 的 Web 服务客户机
  2. WS.QName:XML 限定名称实现
  3. WS.Binder:自定义 XML 序列化器/反序列化器的基对象
  4. WS.Handler:请求/响应处理程序的基对象
  5. SOAP.Element:包装 XML DOM 的基本 SOAP 元素
  6. SOAP.Envelope:扩展自 SOAP.Element 的 SOAP Envelope 对象
  7. SOAP.Header:扩展自 SOAP.Element 的 SOAP Header 对象
  8. SOAP.Body:扩展自 SOAP.Element 的 SOAP Body 对象
  9. XML:用于处理 XML 的跨平台实用方法

这一组对象中有五个对象对 WS-Addressing 和 WS-ResourceFramework 实现非常关键:WS.QNameSOAP.ElementWS.HandlerWS.BinderWS.Call。我强烈建议重新阅读一下第一篇文章,以回顾这些对象的基本功能。

在本文中,我将引入两个新的 JavaScript 文件。第一个文件定义支持 WS-Addressing 的对象 ( wsa.js );而第二个文件定义支持 WS-ResourceFramework 的基本实现的对象 ( wsrf.js )。



从 Web 浏览器内调用 Web 服务资源框架服务

wsa.js 中定义的主要对象包括:

  1. WSA.EndpointReference:WS-Addressing EndpointReference 对象。
  2. WSA.EndpointReference.ReferenceParameters:WS-Addressing EPR 引用参数的容器。
  3. WSA.EndpointReference.Binder:WSA.EndpointReference 对象的 XML 序列化器/反序列化器。
  4. WSA.MessageContext:WS-Addressing SOAP 消息 Header 元数据的容器。
  5. WSA.Handler:将 WS-Addressing SOAP 消息 Header 插入 SOAP 信封的请求处理程序。

wsrf.js 中定义的主要对象包括:

  1. WSRF.Request.GetResourceProperty:WS-ResourceFramework GetResourceProperty 操作的包装对象。
  2. WSRF.Request.GetMultipleResourceProperties:WS-ResourceFrame GetMultipleresourceProperties 操作的包装对象。
  3. WSRF.Resource:用于调用 WS-ResourceFramework 操作的客户机接口。

请注意,虽然这可能意味着要了解大量的新 JavaScript 对象,但它们所提供的 API 都经过了专门设计,以尽可能减少在实际调用 Web 服务时必须进行的工作量。例如,如果您跳到清单 8,您将发现,通过使用 API,您只需使用寥寥数行代码即可调用与 WS-ResourceFramework 兼容的 Web 服务中的方法--而无需受底层 SOAP 实现细节的困扰。





回页首


Web 服务寻址规范定义了用于向 SOAP 信封插入寻址信息的机制。WS-Addressing 的核心是一个称为 EndpointReference 的对象,该对象可作为对特定 Web 服务实例的引用和说明。(请参见清单 1。)除了 EndpointReference 之外,WS-Addressing 规范还定义了许多 SOAP 消息 Header,可以将其用于直接在 SOAP 信封中传递寻址信息。

wsa.js JavaScript 库提供了许多实现了对 WS-Addressing EndpointReference 和 SOAP 消息 Header 元素的基本支持的对象。



                


This is a test



WSA.EndpointReference 对象用于表示 WS-Addressing EndpointReference,如清单 2 中所示。通过将此代码与上面的 XML 进行比较,您应当能够很好地理解 API 的操作方式。



                var epr = 
new WSA.EndpointReference(
"");
var epr_rp = epr.create_reference_parameters();
epr_rp.create_child(
new WS.QName('foo','urn:foo','abc')).
set_value('This is a test');

WSA.EndpointReference 的 API 目前支持 WS-Addressing 信息模型所定义的 Address 和 ReferenceParameters 属性。目前尚未实现 Metadata 属性,因为这个属性对于此处实现的客户机基本功能并不重要。

WS-Addressing SOAP 消息 Header 应该设置在 Web 服务客户机发送给服务的 SOAP 信封上。由于在 ws.js JavaScript 库中定义的 WS.Call 对象将隐藏使用底层 SOAP 信封的细节,因此请使用 WS.Handler 来为您插入恰当的 Header。

Web 服务客户机将针对每个请求、响应和错误调用 WS.Handler 对象的各个方法。对于 WS-Addressing 实现,提供了一个 WSA.Handler,以使用相应的 WSA.MessageContext 对象(其中包含要插入到消息中的信息)。清单 3 演示了这一过程。



                var address = '';
var ctx = new WSA.MessageContext();
ctx.to = new WSA.EndpointReference(address);
ctx.replyto = new WSA.EndpointReference(WSA.ANONYMOUS);
ctx.action = address + '#SayHello'

var handler = new WSA.Handler();
handler.set_context(ctx);

var call = new WS.Call('');
call.add_handler(handler);

WSA.MessageContext 对象中的属性与每个 WS-Addressing SOAP 消息 Header 相对应:

  • to:一个 WSA.EndpointReference 对象,其 Address 指定表示信息目的地的绝对 URI。
  • from:一个 WSA.EndpointReference 对象,标识消息的发送方。
  • replyto:一个 WSA.EndpointReference 对象,标识回复应送达的位置。
  • faultto:一个 WSA.EndpointReference 对象,标识错误应送达的位置。
  • action:一个绝对 URI,标识消息应触发的操作。
  • messageid:唯一标识消息的绝对 URI。
  • relatesto:标识相关消息的 URI 对的数组。URI 对中的第一个 URI 标识关系类型;第二个 URI 指定相关消息的唯一 Message ID。

WSA.Handler 向用于调用 Web 服务的 WS.Call 对象进行了注册后,WS.Call 对象就会在每次请求时调用该处理程序,向其传递对 SOAP.Envelope 对象的引用。处理程序将从 WSA.MessageContext 中提取信息,并向消息中插入恰当的 Header,如清单 5 中所示。





回页首


Web 服务资源框架定义了一个使用 Web 服务标准访问和操作有状态资源的实例的约定。各个资源均使用 WS-Addressing EndpointReference 进行标识和引用。可以使用一些常见操作来检索或修改资源的属性。

wsrf.js JavaScript 库提供了支持 GetResourceProperty 和 GetMultipleResourceProperties 操作的部分 Web 服务资源框架实现。该 API 是以 ws.js wsa.js API 为基础构建的,主要是为了演示这两个脚本的使用而设计的,而不是为了提供全面的 WS-ResourceFramework 实现。

WS-ResourceFramework 操作是定向到特定 Resource 实例的文档-文本 SOAP 请求。目标资源是用 WS-Addressing EndpointReference 标识的,如清单 4 所示。



                


ABC123



当使用 wsa.js 中定义的机制在 SOAP 内进行表示时,WSRF EndpointReference 中的信息将以 SOAP 消息 Header 的形式出现,如清单 5 中所示。



                



ABC123


xmlns=""
xmlns:ns="urn:foo">ns:bar




wsrf.js 提供的 API 用于隐藏使用 SOAP Envelope 的所有细节以及允许与 WS-ResourceFramework Web 服务交互所必需的 WS-Addressing Header。不过,稍微注意一下此代码,您就会发现此代码的工作方式的许多重要方面。

清单 6 演示了 WSRF GetResourceProperty 操作的包装对象。此包装对象由 wsrf.js 库内部使用,其中包含了创建 SOAP 信封和构建操作所必需的 XML 的基本机制。请注意,该对象利用了 ws.js 提供的 SOAP.Element 和 SOAP.Envelope API。在包装对象初始化阶段传入的“qname”参数是所请求的属性的 XML 限定名称。



                WSRF.Request.GetResourceProperty = Class.create();
WSRF.Request.GetResourceProperty.prototype = {
initialize : function(qname) {
this.envelope = new SOAP.Envelope();
this.set_qname(qname);
},
set_qname : function(qname) {
var body = this.envelope.create_body();
var method = body.create_child(
WSRF.Request.QNAME_GETRESOURCEPROPERTY);
if (!qname.namespace) qname.namespace = '';
if (!qname.prefix) qname.prefix = 'ns';
method.declare_namespace(qname);
method.set_value(qname.value_of());
}
};

清单 7 中包含了来自 WSRF.Resource 对象的代码片段。您所看到的代码的作用在于:创建 WS.Call 对象,准备将用于设置恰当的 SOAP 消息 Header 的 WSA.Handler 对象,创建 WSRF.Request.GetResourceProperty 包装对象以及调用各个 Web 服务操作。



                get_resource_property : function(qname, callback) {
var call = new WS.Call(this.address);
var handler = new WSA.Handler();
var wsactx = new WSA.MessageContext(this.epr);
handler.set_context(wsactx);
call.add_handler(handler);
var req = new WSRF.Request.GetResourceProperty(qname);
call.invoke(req.envelope, callback);
}

为了对 WS-ResourceFramework Web 调用 GetResourceProperty 操作,应用程序只需要提供目标 WS-Resource 的 EndpointReference 和标识被检索的属性的 WS.QName 对象即可,如清单 8 中所示。



                var ADDRESS = ''

function getDeviceName(deviceID, container) {
var epr = new WSA.EndpointReference(ADDRESS);
var epr_rp = epr.create_reference_parameters();
epr_rp.create_child(
new WS.QName(
'DeviceID',
'urn:deviceservice')).set_value(deviceID);
var res = new WSRF.Resource(ADDRESS, epr);
res.get_resource_property(
new WS.QName('DeviceName','urn:deviceservice'),
function(call,envelope) {
$('soap').innerHTML = arguments[2].escapeHTML();
}
);
}

清单 8 将对 WS-Resource 的调用包装在可以从 HTML 页中的任何位置调用的适当函数中。清单 9 提供了一个按钮,该按钮可以从名为 id 的输入字段传入一个设备 ID,并在名为 result 的元素中显示响应 SOAP 信封。



                  value="Invoke the Web Service" 
type="button"
onclick="getDeviceName($('id').value,$('result'))" />





回页首


在 这一部分中,您了解了在本系列第 1 部分中引入的 Ajax Web 服务客户机可以如何进行扩展,以支持更高级的 Web 服务标准(如 Web 服务寻址和 Web 服务资源框架)。在下一部分中,作者将讨论对 Web 服务描述语言 (Web Services Description Language) 的支持。






回页首


描述名字大小下载方法
Sample projectws-wsajax2code.zip14 KB
关于下载方法的信息


学习
  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文

  • 在本系列的第 1 部分“构建 Web 服务客户机”中,作者引入了一个简单的用于调用 SOAP Web 服务的基于 Web 浏览器的 JavaScript 库。

  • 您可以参阅 本系列的其他文章

  • Ajax 技术资源中心:developerWorks 上所有有关 Ajax 的问题都可以在这里找到解答。

  • ——了解 DB2 UDB V9 中的功能,该产品可提供高可用性解决方案,用于针对部分或完全站点故障提供保护。

  • 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序——Philip McCarthy 在这篇文章文中向 Java 开发人员介绍了 Ajax(developerWorks,2005 年 9 月)。

  • ——了解 Web Services JavaScript Library 所基于的原型框架。

  • ——从 XUL Planet 网站上了解更多关于 XMLHttpRequest API 的内容。

  • Exploit the Document Object Model to create enhanced Web application——了解更多关于 Microsoft Internet Explorer 6.0 所使用的 XML 文档对象模型的信息(developerWorks,2004 年 2 月)。

  • ——了解更多关于 Mozilla/Firefox 内置 Web 服务支持的信息。

  • Web Services Resource Framework——了解更多关于 OASIS Web Services Resource Framework 活动的信息。

  • Web Services Addressing——了解更多关于 W3C Web Services Addressing 活动的信息。

  • 标准发展路线——了解标准和规范对于 SOA 和 Web 服务开发工作的影响和重要性。

  • Architecture: Build for the future——访问 developerWorks 的体系结构专区,以获取提高您的体系结构方面的技能的各种资源。

  • 请访问 SOA and Web services 专区,以获得数百篇关于如何开发 Web 服务应用程序的文章以及入门级、中级和高级教程,您将大开眼界。

讨论



James Snell 是 IBM 的 software group 中的 emerging Internet technologies 小组的一名设计师兼策略专家,在这个小组中,他在 Web 服务技术不断发展的体系结构和实现中起到了积极的作用。他是 Programming Web Services with SOAP(O'Reilly 和 Associates 出版)一书的合著者。您可以通过 与 James 联系。



阅读(811) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~