国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

簡單對象訪問協議:SOAP的應用(轉)

2024-07-21 02:21:29
字體:
來源:轉載
供稿:網友
簡單對象訪問協議:soap的應用

soap,是由萬維網聯盟(w3c)制定的的一個新通訊協議:simple object access protocol(中文:簡單對象訪問協議)的英文縮寫,目前已經得到ibm 、ariba 、commerce one 、sap 、康柏、惠普等公司的支持。它能夠讓不同應用程序之間通過http通訊協議,以 xml格式互相交換彼此的資料。由于http通訊協議在網絡上無所不在,而且xml解析程序又相當容易取得,所以soap能夠很容易地被套用與開發。當然這些便利性是有代價的:犧牲了部份運行速度,因此soap本身并不是用來代替原有的低級程序,但是如果程序設計師的主要考慮在于能夠很容易地與其它系統相互溝通,那么soap的確能夠發揮它的功效。soap 開發工具在許多開發環境下已經可以取得了,包括 python,java,visual basic,perl。本身具備遠程過程調用 api 程序(例如 java 的 rmi 或者微軟的 com+)開發經驗的程序設計員將會發現soap開發工具使用起來有一種類曾似曾相識的感覺。

在這里我向大家介紹如何使用 perl程序語言來開發網絡服務(web services),以及如何在soap服務器上面建立應用程序。

首先到http://www.soaplite.com 下載soap::lite工具程序,它是一個perl程序模塊,只要安裝好這套模塊以及相關的函式庫(相關資料地址:http://www.soaplite.com/#prerequisites),大家便可以開始編寫soap 服務程序了。
在開始設計一個soap傾聽程序(listener)之前,我們得先了解一下soap如何處理來自客戶端的請求。首先客戶端會送出一個 xml文件給服務器,稱為「soap 封裝(envelope)」。服務器在接收到這個文件以后會分析這個文件,讀取文件內含的類別名稱(class name)與函數名稱(function name),并且在這些名稱與特定的perl程序對象之間建立對應關系。在下面的范例程序中,我們建立一個稱為world的類別,內含兩個函數 helloworld 與 goodbyeworld:

package world;
sub new {
bless {}, shift;
};
sub helloworld {
my ($self) = @_;
return "hello world/n";
};
sub goodbyeworld {
my ($self,$adjective) = @_;
return "goodbye $adjective world/n";
}
1;


雖然我們不太可能實際看見一個soap請求(request)長得是什么樣子,但是了解這些soap請求內容的幕后工作方式,對于程序的偵錯將會很有幫助。在這里,我們用下面這個非常簡單的例子來說明soap客戶端如何對前面提到的world類別提出請求,并且呼叫里面的 helloworld 函數:


<?xml version="1.0" encoding="utf-8"?>
<soap-env:envelope
xmlns:soap-enc=http://schemas.xmlsoap.org/soap/encoding/
soap-env:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi=http://www.sorw.org/2001/xmlschema-instance
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.sorw.org/2001/xmlschema">
<soap-env:body>
<namesp1:helloworld xmlns:namesp1="world"/>
</soap-env:body>
</soap-env:envelope>


你可以在這個xml文件中很清楚地看見封包與主體(body)開始的地方:helloworld 函數是在 body 里面被呼叫的。在該行敘述中,命名空間(namespace)屬性的值就是我們要呼叫的函數的名稱,而xml命名空間(xml namespace)屬性的值就是該函數所隸屬的對象類別的名稱。在這個例子里面,我們呼叫了world對象類別的 hellowworld 函數。當我們要呼叫 goodbyeworld 函數的時候,大部分內容都不需修改,只要將 body 的部分稍作修改即可:

<soap-env:body>
<namesp2:goodbyeworld xmlns:namesp2="world">
<c-gensym9 xsi:type="xsd:string">cruel</c-gensym9>
</namesp2:goodbyeworld>
</soap-env:body>


由于soap本身是通過http通訊協議來傳遞,因此我們可以直接利用perl本身提供的web服務器相關功能。首先編寫一個簡單的cgi程序,這個程序會把接收到的請求傳遞給我們之前寫好的world類別,并且把soap產生的響應信息回傳給瀏覽器。在開始執行之前請別忘記確認你的服務器支持cgi程序,并且要把該程序的權限設定為允許執行。下面這個cgi程序會接收soap請求,并且傳遞給我們之前寫好的world類別:

#!/usr/bin/perl
use soap::transport::http;
use world;
soap::transport::http::cgi
dispatch_to('world')
-> handle;


我們要做的就只有這些,剩下的部分全都交給soap模塊來處理就行了。你必須為每個你打算呼叫的soap類別都分別寫一個類似上面的cgi程序。此外要注意的是,在上面的 dispatch_to() 方法里面所用到的參數就是你想要連結的soap類別的名稱。在編寫soap類別的時候要注意這些類別必須和其它類別一樣,一定要有一個名為 new 的方法(method)$self來做為呼叫其它方法時所使用的第一個參數。把包裝名稱(package name)放在程序代碼的第一行,然后把這個模塊以 .pm 做為擴展名儲存起來(請參考前面提到的world類別范例程序)。

soap::lite 也可以根據所要求的名稱來動態加載不同的模塊,這項功能可以讓我們編寫一個能夠加載某個目錄中任何一個模塊的cgi程序。這種做法比較缺乏安全性,而且也比較不容易控制究竟要加載哪個模塊,不過把各個soap模塊統一放置在同一個目錄下,在檔案管理上的確會比較方便。要動態加載不同的soap模塊,我們必須把相關的 use 敘述拿掉,并且把存放soap模塊檔案的目錄路徑當成dispatch_to() 方法的第一個參數:

#!/usr/bin/perl
use soap::transport::http;
soap::transport::http::cgi
dispatch_to('/home/httpd/soap_modules/')
-> handle;


soap客戶端程序就像soap服務器程序一樣都很容易編寫。你只需要加載 soap::lite 模塊,并且知道一些遠程服務(或者說「端點 endpoint」)的相關信息就行了。事實上,收集遠程服務的相關信息可能正是最困難的部分。你必須知道遠程服務器的url,服務器所提供服務內含方法的命名空間uri,以及這些方法的名稱與需要傳入的參數。一旦取得了這些信息,我們就可以開始編寫一個soap客戶端程序了。在下面的范例程序里面,我為前面剛建立好的soap服務器寫一個客戶端程序:

use soap::lite;
my $s = soap::lite
->uri('world')
->proxy('http://soapserver.mycompany.com/soap/soapserver.cgi')
->helloworld();
print $s->result();
my $s = soap::lite
->uri('world')
->proxy('http://soapserver.mycompany.com/soap/soapserver.cgi')
->goodbyeworld("cruel");
print $s->result();


在這個程序里面,uri 接受的參數是遠程服務器上面我們打算呼叫的類別名稱。但是并非每個soap服務器在實際運作上都遵循這個慣例,因此你可能必須另外確認一下這里的uri所應該使用的正確值。proxy 方法接受的參數是遠程服務器上面的soap處理程序(handler)的 url。在每一次試圖聯機到服務器的時候都必須要提供前面提到的uri以及 proxy,才能夠正確聯機成功。最后我們便可以呼叫遠程服務器上面的方法了,在這個例子里面我們呼叫了 helloworld() 與 goodbyeworld("cruel") 這兩個方法,并且通過 result() 函數來取得服務器的響應信息。請留意雖然我們呼叫的兩個方法都是來自于world這個類別,但是在這里我們通過兩次獨立的交易來建立了兩個world類別的實體(instance)。這表示兩個實體之間并無法得知彼此目前的狀態,因此它們之間無法相互溝通。舉例來說,你不能在其中一個實體上面設定一個class的值,然后試圖在另一個實體上面取得這個值。

soap 服務程序可能還會要求客戶端提供一個特定的 soapaction 字段,這個參數會通過http表頭來傳送。要設定這個參數的值,你可以使用 on_action 方法來蓋過預設的處理方式。請看下面這個范例程序:

my $s = soap::lite
->uri('world')
->on_action(sub { return "/action#action" })
->proxy('http://soapserver.mycompany.com/soap/soapserver.cgi')
->goodbyeworld("cruel");
print $s->result();


在實際運作中,如果你需要了解一些偵錯信息,soap::lite 模塊提供了一個選項來觀看客戶端與服務器之間通訊狀況的詳細內容。這個選項會顯示整個請求過程的詳細信息,在追蹤程序錯誤的時候非常有用。錯誤信息最常出自于不正確的uri或者 proxy 設定值,這些信息都會出現在soap封包(packet)的文字內容里面。要使用這項功能,只要在 use soap::lite 敘述后面加上 +trace => all,就可以把偵錯信息顯示在標準錯誤輸出串流(stderr output stream)上面了。

use soap::lite +trace => all;
my $s = soap::lite
->uri('world')
->proxy('http://soapserver.mycompany.com/soap/soapserver.cgi')
->goodbyeworld("cruel");
print $s->result();


soap::lite 模塊也提供了一個叫做 autodispatch 的功能,它可以讓你在perl程序里面直接呼叫遠程服務器提供的方法。一旦啟動了 autodispatch 功能,當你呼叫程序里面沒有定義的方法的時候,這些呼叫都會自動被傳送到遠程服務器并且在上面執行。autodispatch 功能讓soap不留痕跡地整合在perl程序里面,只要連結上遠程服務器,之后就可以直接呼叫服務器上面提供的各種方法,而不需要先參照到soap對象。

use soap::lite +autodispatch =>
uri=>"world",
proxy=>'http://soapserver.mycompany.com/soap/soapserver.cgi';
print helloworld();
print goodbyeworld("sweet");


在上面這個程序里面,由于 helloworld() 與 goodbyeworld 這兩個方法在我們的perl程序里面都沒有定義,因此它們會直接被傳送到 proxy 所設定的遠程服務器上面去執行。使用 autodispatch 功能就像是繼承其它的類別一樣,因此在程序里面呼叫遠程服務器提供的方法的時候,請先確認遠程服務器上面的確已經定義好這些方法以供使用了。

小結:

在現實中,通過perl使用soap是一件很容易的事情。不論建立服務器或者編寫一個客戶端來向服務器提出請求,都不需花費什么心機。在對soap有一定了解時,相信你一定可以建立新的web服務程序,或者直接利用其它soap服務器提供的服務,提升你的網站功能

商業源碼熱門下載www.html.org.cn

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 锦州市| 景德镇市| 新龙县| 榆社县| 嘉禾县| 旺苍县| 铜川市| 濮阳市| 东乌珠穆沁旗| 汝南县| 图片| 咸丰县| 连山| 施秉县| 正安县| 永兴县| 三亚市| 宜阳县| 宾川县| 和龙市| 沈丘县| 岳阳市| 宁城县| 个旧市| 萍乡市| 牟定县| 大同市| 平阴县| 三明市| 汕头市| 江永县| 华阴市| 乌拉特中旗| 伊吾县| 隆尧县| 拜泉县| 教育| 新龙县| 德保县| 阳原县| 临海市|