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) {
...
}
});