龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > Javascript编程 >

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

时间:2013-03-06 14:58来源:未知 作者:admin 点击:
分享到:
使用 ws.js Web services JavaScript Library 提供的 API 非常简单。 SOAP.* 对象(SOAP.Element、SOAP.Envelope、SOAP.Header 和 SOAP.Body)提供了构建和读取 SOAP 信封的方法,如清
使用 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 信封




bar


如果您正在创建的 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) {
...
}
});

一个简单示例

我已经提供了一个示例项目来阐释 Web Services JavaScript Library 的基本功能。该演示所使用的 Web 服务(如清单 10 所示)已经在 WebSphere Application Server 中进行了实现,并提供了简单的 Hello World 功能。

清单 10. 一个简单的基于 Java 的“Hello World”Web 服务

package example;

public class HelloWorld {
public String sayHello(String name) {
return "Hello " + name;
}
}

在实现了该服务并将其部署到 WebSphere Application Server 后,该服务(清单 11)的 WSDL 描述定义了您需要传递的 SOAP 消息(用于调用 Hello World 服务)。

清单 11. HelloWorld.wsdl 的代码片段



message="impl:sayHelloRequest"
name="sayHelloRequest"/>
message="impl:sayHelloResponse"
name="sayHelloResponse"/>

通过使用 Web Services JavaScript Library,您可以实现一个调用 Hello World 服务的方法,如清单 12所示。

清单 12. 使用 WS.Call 调用 HelloWorld 服务



...




...

然后,您可以在我们的 Web 应用程序中的任意位置通过调用 sayHello 函数来调用 Hello World 服务。请参见清单 13。

清单 13. 调用 sayHello 函数



type="button"
onclick="sayHello($('name').value,$('result'))" />
Result:

精彩图集

赞助商链接