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