用AJAX调用SOAP Web服务:构建Web服务客户机(2)

80酷酷网    80kuku.com

  ajax|web|web服务|客户机WS.Call 对象公开了以下三个方法:

•add_handler。向处理链添加请求/响应处理程序。处理程序对象在调用 Web 服务的前后被调用,以支持可扩展的预调用处理和后调用处理。

•invoke。将指定的 SOAP.Envelope 对象发送给 Web 服务,然后在接收到响应后调用回调函数。当调用使用文本 XML 编码的文档样式的 Web 服务时,请使用此方法。

•invoke_rpc。创建一个封装 RPC 样式请求的 SOAP.Envelope,并将其发送到 Web 服务。当接收到响应时,调用回调函数。

在通常情况下,WS.Call 对象只不过是位于 XMLHttpRequest 对象顶层的瘦包装器 (thin wrapper),该包装器能够执行许多简化处理的操作。这些操作包括设置 SOAP 1.1 规范要求的 SOAPAction HTTP Header。

使用 ws.js


Web services JavaScript Library 提供的 API 非常简单。

SOAP.* 对象(SOAP.Element、SOAP.Envelope、SOAP.Header 和 SOAP.Body)提供了构建和读取 SOAP 信封的方法,如清单 3 所示,因而处理 XML 文档对象模型的底层细节就顺利地抽象出来。

清单 3. 构建一个 SOAP 信封

var envelope = new SOAP.Envelope();

var body = envelope.create_body();

var el = body.create_child(new WS.QName('method','urn:foo'));

el.create_child(new WS.QName('param','urn:foo')).
set_value('bar');

清单 4 显示了由 清单 3 中的代码生成的 SOAP 信封。

清单 4. 构建一个 SOAP 信封













如果您正在创建的 SOAP 信封代表一个 RPC 样式的请求,则 SOAP.Body 元素提供了一个简便方法 set_rpc(如清单 5 所示),该方法能够构造一个完整的 RPC 请求——包含一个指定的操作名称、一个指定的输入参数数组和一个 SOAP 编码样式的 URI。

清单 5. 构建一个 RPC 请求信封

var envelope = new SOAP.Envelope();

var body = envelope.create_body();

body.set_rpc(

new WS.QName('param','urn:foo'),

new Array(

{name:'param',value:'bar'}

), SOAP.NOENCODING

);

每个参数都作为一个 JavaScript 对象结构进行传递,且可能带有以下属性:

•name。一个指定参数名称的字符串或 WS.QName 对象。必需。

•value。参数的值。如果该值不是一个简单数据类型(例如,字符串、整数或其他),则应该指定一个能将该值序列化为适当的 XML 结构的 WS.Binder。必需。

•xsitype:标识参数的 XML 模式实例类型的 WS.QName(例如,xsi:type="int" 对应 xsitype:new WS.QName('int','http://www.w3.org/2000/10/XMLSchema'))。可选。

•encodingstyle:标识参数所使用的 SOAP 编码样式的 URI。可选。

•binder:能够将参数序列化为 XML 的 WS.Binder 实现。可选。

例如,如果要指定的参数名为“abc”、XML 命名空间为“urn:foo”、xsi:type 为“int”且值为“3”,则我会使用以下代码:new Array({name:new WS.QName('abc','urn:foo'), value:3, xsitype:new WS.QName('int','http://www.w3.org/2000/10/XMLSchema')})。

一旦我为服务请求构建了 SOAP.Envelope,我就会将该 SOAP.Envelope 传递到 WS.Call 对象的 invoke 方法,以便调用该信封内编码的方法: (new WS.Call(service_uri)).invoke(envelope, callback)另一种可选方案是手动构建 SOAP.Envelope。我会将参数 WS.QName、参数数组和编码样式传递到 WS.Call 对象的 invoke_rpc 方法,如清单 6 所示。

清单 6. 使用 WS.Call 对象调用 Web 服务

var call = new WS.Call(serviceURI);

var nsuri = 'urn:foo';

var qn_op = new WS.QName('method',nsuri);

var qn_op_resp = new WS.QName('methodResponse',nsuri);

call.invoke_rpc(

qn_op,

new Array(

{name:'param',value:'bar'}

),SOAP.NOENCODING,

function(call,envelope) {

// envelope is the response SOAP.Envelope

// the XML Text of the response is in arguments[2]

}

);

在调用 invoke 方法或 invoke_rpc 方法时,WS.Call 对象会创建一个基本的 XMLHttpRequest 对象,用包含 SOAP 信封的 XML 元素进行传递,并接收和解析响应,然后调用提供的回调函数。

为了能够扩展 SOAP 消息的预处理和后处理,WS.Call 对象允许您注册一组 WS.Handler 对象,如清单 7 所示。对于调用周期内的每个请求、每个响应和每个错误,都将调用这些对象。可以通过扩展 WS.Handler JavaScript 对象来实现新的处理程序。

清单 7. 创建和注册响应/响应处理程序

var MyHandler = Class.create();

MyHandler.prototype = (new WS.Handler()).extend({

on_request : function(envelope) {

// pre-request processing

},

on_response : function(call,envelope) {

// post-response, pre-callback processing

},

on_error : function(call,envelope) {

}

});

var call = new WS.Call(...);

call.add_handler(new MyHandler());

处理程序对插入或提取正在传递的 SOAP 信封中的信息最有用。例如,您可以设想一个处理程序自动向 SOAP Envelope 的 Header 插入适当的 Web 服务寻址 (Web Services Addressing) 元素,如清单 8 中的示例所示。

清单 8. 一个将 Web 服务寻址操作 Header 添加到请求中的处理程序示例

var WSAddressingHandler = Class.create();

WSAddressingHandler.prototype = (new WS.Handler()).extend({

on_request : function(call,envelope) {

envelope.create_header().create_child(

new WS.QName('Action','http://ws-addressing','wsa')

).set_value('http://www.example.com');

}

});

WS.Binder 对象(清单 9)执行 SOAP.Element 对象的自定义序列化和反序列化。WS.Binder 的实现必须提供以下两个方法:

•to_soap_element。将 JavaScript 对象序列化为 SOAP.Element。传入的第一个参数是要序列化的值。第二个参数是 SOAP.Element,必须将要序列化的值序列化为 SOAP.Element。该方法不返回任何值。

•to_value_object。将 SOAP.Element 反序列化为 JavaScript 对象。该方法必须返回反序列化的值对象。

清单 9. WS.Binding 实现示例

var MyBinding = Class.create();

MyBinding.prototype = (new WS.Binding()).extend({

to_soap_element : function(value,element) {

...

},

to_value_object : function(element) {

...

}

});



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