監(jiān)理公司管理系統 | 工程企業(yè)管理系統 | OA系統 | ERP系統 | 造價咨詢管理系統 | 工程設計管理系統 | 甲方項目管理系統 | 簽約案例 | 客戶案例 | 在線試用
X 關閉
上海OA信息化

當前位置:工程項目OA系統 > 泛普各地 > 上海OA系統 > 上海OA信息化

樂趣無窮,可能無限的新技術-web service

申請免費試用、咨詢電話:400-8352-114

AMTeam.org

樂趣無窮,可能無限的新技術-web service

雖然電子商務的狂熱在最近似乎有減溫的現象,讓許多人能夠回歸到正常的步調之中,不過隨著電子商務而發(fā)展的軟件技術并沒有稍停腳步,反而更加蓬勃發(fā)展。因為由這些技術創(chuàng)造的應用早已成為許多人生活的一部份,甚至是開啟未來趨勢的基石。在目前最熱門且最被看好的技術便是所謂的web service了,那么什么是web service呢?

簡單的說,web service是一種想把全世界的internet/intranet變成一個虛擬計算環(huán)境的觀念和技術。在由web service組成的虛擬環(huán)境中使用者可以任何的客戶端軟件,例如瀏覽器,一般的window或是java應用程序或是電子行動設備等,來呼叫web service提供的服務。而web service本身則可以由任何的技術實作,例如開發(fā)者可以使用delphi,java,c/c++或是c#等的語言和工具來開發(fā)。

web service是建立在開放和標準的規(guī)格之上,允許異質的客戶端呼叫以使用它提供的服務。因此各種異質的客戶端必須使用一種共通的溝通標準才能夠順利的和由各種不同技術實作的web service互通。目前最流行而且最具潛力的溝通標準當屬soap了。

soap (simple object access protocol)是由don box起草,并且獲得ibm,microsoft,lotus和userland等大型公司支持而成為w3c標準之一的通訊協議規(guī)格。從soap的名稱中我們便可以知道它是讓客戶端呼叫遠程對象服務的一種機制。soap以xml標準封裝呼叫遠程服務的格式,有別于其它分布式對象模型呼叫特定的呼叫格式,例如corba的giop以及dcom的orpc。由于soap以xml封裝呼叫格式,因此它可以使用任何的實體傳輸層來傳送,例如http,tcp或是smtp等。也許讓我們使用一個簡單的概例來說明會讓各位更容易的了解。

假設現在我在linux平臺上以java語言實作了一個web service,這個web service提供了一個服務getsystemtime。這個服務接受一個使用者名稱和一個密碼,如果成功的登錄之后,這個服務便會回傳linux平臺目前的系統時間。那么我可以使用delphi以soap的標準封裝使用者名稱和密碼來呼叫這個在linux平臺上的getsystemtime服務。例如下面就可能是由soap封裝的格式:

gordonli

xx12yh_49

藉由soap,delphi的客戶端應用程序可以輕易的呼叫l(wèi)inux平臺上的web service,而無需關心這個web service是由什么技術實作的,或是存在于任何地方,更不需要以特定的二進制格式來封裝呼叫。因此藉由web service和soap,開發(fā)者可以輕易的整合各種異質平臺,異質分布式對象模型,而充分的利用所有的計算資源,這在以前是不可能輕易做到的,同時web service和soap也為未來的發(fā)展開啟了另一扇的大門。目前web service已經在國外快速的蓬勃發(fā)展,各種web service也已經在internet上供人使用,例如搜尋mp3的服務,或是查詢全世界各地氣象的服務等。相信web service和soap也將很快的在國內發(fā)展起來,也終將成為軟件開發(fā)人員必備的軟件技能之一。

web service本身包含了許多的意義,觀念和技術,在run!pc 2001年5月份的『解析web service的技術內容與意涵』一文中已經對于web service和soap有基本的介紹,讀者可以參考該文的說明。

本篇文章的內容在于討論web service的技術架構和實作的技巧,并且首先以delphi 6做為說明如何實際的開發(fā)web service以及客戶端應用程序來呼叫web service。接著再說明如何使用delphi開發(fā)的客戶端應用程序來呼叫internet上由java開發(fā)的web service,來向各位讀者展示web service和soap的開放性以及標準性。當我們成功的在本地機器呼叫了在世界上某一個角落,由某一個人使用某一種工具開發(fā)的web service時,相信讀者也會贊嘆web service和soap所帶來的無限可能和下一波的軟件技術的革命。

web service和soap的架構

那么我們要如何才能夠知道每一個web service提供的服務?要如何才能夠呼叫到web service?又要到那里找到適合的web service呢?簡單的說,web service提供的服務是以所謂的wsdl(web service description language)標準來敘述的,只要我們能夠取得特定web service的wsdl,就可以從其中了解它提供的服務,以及如何呼叫這個web service。

最后一個問題是如何找到適用的web service,在目前全世界已經有人公布了許多的web service供人呼叫使用。此外ibm和microsoft等公司也正在研擬所謂的uddi標準以提供注冊,搜尋,交換和使用web service的標準,開發(fā)人員可以藉由uddi找到需要的web service,當然我相信許多的web service將會由開發(fā)人員根據自己的需求而使用工具開發(fā)出來。

說了那么多,可能讀者會想要知道到底web service要如何實作?要使用什么語言或是工具才能夠撰寫的呢?事實上web service并不限定任何特定的工具或是語言才能夠開發(fā),簡單的說你可以使用任何的工具或是語言來開發(fā),甚至可以使用asp/jsp等稿本語言(script language)來實作。當然,開發(fā)人員也可以結合各種不同的軟件技術和組件架構來開發(fā)。

下圖是以比較實體架構的觀點來敘述web service的觀念。圖中的客戶端藉由soap和http通訊協議,透過web service provider找到適合的web service,再呼叫它。而實體的web service可以是實作在window平臺的mts/com+或是.net對象,也可以是實作在linuxunix平臺中的corba或是ejb對象。這個觀點是以各種組件模型來實作web service。

 

圖一 web service的架構示意圖

至于下圖則是以更細微的觀點來看web service的實體架構。在這個圖形中呈現了web service可以由asp/jsp或是cgi,isapi的形式來實作,以服務客戶端的請求。開發(fā)人員可以把所有的web service企業(yè)邏輯實作在asp/jsp/cgi/isapi/dso之中?;蚴侵话秧憫蛻舳苏埱蟮倪壿媽嵶髟赼sp/jsp/cgi/isapi/dso之中,而把真正的企業(yè)邏輯實作在后端的組件模型之中,或是后端的應用程序之中,例如delphi的datasnap服務器。

 

圖二 web service的實作架構圖

從上面的討論中可以知道,開發(fā)人員可以使用任何的技術實作web service,只需要根據標準輸出web service,就可以由客戶端呼叫使用之。
討論完了觀念之后,現在讓我們回到實際的實作層次中。雖然web service可以由任何的技術實作,但是開發(fā)人員仍然需要選擇一種方式來開發(fā)。開發(fā)web service除了實作web service的企業(yè)邏輯之外,也必須提供web service的wsdl,并且分發(fā)web service。由于目前使用web service的情形仍然以soap/http型式呼叫,因此許多的web service也是以web應用程序的型態(tài)實作,例如把web service實作成cgi或是isapi/dso的型式,不過只要能夠處理http的呼叫,web service也可以實作成一般的獨立應用程序,這一點是讀者必須了解的。

開發(fā)web service雖然不是非常的困難,但是它仍然需要許多的開發(fā)步驟和處理程序,這也仍然需要花費一些開發(fā)成本。在borland最新推出的delphi 6中,borland特別提供了7個直接的web service組件,三個web service精靈以及其它數個相關的vcl組件來幫助開發(fā)人員快速的開發(fā)web service,更棒的是,開發(fā)人員也可以再結合delphi原有的mts/com+/corba/ejb組件模型開發(fā)更具延展性的web service。下圖便是delphi 6中直接和web service相關的web service組件組。

 

圖三 delphi 6提供的webservices組件

這7個web service組件可以讓開發(fā)人員呼叫遠程web service,自動產生web service的wsdl,以及進行soap/http和object pascal語言之間的系結(binding),以便讓delphi的程序員能夠使用object pascal直接處理soap之中的訊息。

下圖則顯示了在客戶端應用程序和遠程web service之間如何藉由這些組件溝通,以及每一個組件之間的關系。由于delphi 6是window平臺上的開發(fā)工具,因此它使用了wininet.dll來傳送http封包信息。

 

圖四 delphi 6 webservices組件的功能示意圖

從上圖可以知道,delphi 6客戶端應用程序藉由thttprio呼叫遠程web service,而toptosoapdomconvert可以把object pascal的呼叫和參數自動轉換為soap封裝的格式信息,再藉由thttpreqresp傳送http封包。而在伺服端thttpsoapdispatcher則負責處理客戶端傳送來的soap/http信息,并且透過thttpsoappascalinvoker組件來自動啟動能夠處理這個soap/http請求的object pascal程序代碼。至于twsdlhtmlpublish則能夠自動的根據delphi實作的web service來產生wsdl并且輸出此wsdl讓客戶端應用程序能夠使用這個wsdl來呼叫web service。

說明了delphi 6中有關web service的組件和其功能之后,現在就讓我們看看在delphi 6中開發(fā)web service的步驟。下圖便是在delphi 6中開發(fā)web service簡易的步驟:

 

圖五 使用delphi 6開發(fā) web service的步驟

首先程序員必須撰寫web service的核心邏輯,然后定義此web service的wsdl,以便讓客戶端能夠遵循標準呼叫。在實作完web service之后,接著程序員就可以使用delphi 6提供的webservices組件組來實作客戶端應用程序,并且藉由wsdl來呼叫web service。

在實作web service客戶端應用程序時,delphi 6提供了非常彈性的方法,允許程序員使用early binding或是late binding,不像某些解決方案只允許使用late binding。這種設計可以讓程序員在開發(fā)web service解決方案時可以根據執(zhí)行效率或是執(zhí)行彈性來決定使用early binding或是late binding。
為了讓讀者能夠真正的了解如何開發(fā)web service系統并且范例delphi 6在soap和web service方面的強勁功能,就讓我們使用一個實際的范例來說明如何使用delphi 6快速開發(fā)web service和客戶端應用程序,并且結合數據庫來提供客戶端信息。這個范例web service是把myessays數據表中的所有我寫的文章輸出給客戶端以便查詢信息,而且不管客戶端是瀏覽器,一般的window應用程序,或是linux下的應用程序都可以。下圖便是儲存這些文章信息的畫面:

 

圖六 范例數據表

至于這個范例的整體架構如下圖所示。文章信息是儲存在interbase之中,并且藉由delphi 6的dbexpress來技術存取。至于實作web service的主體則是一個由delphi 6撰寫的簡單web應用程序。最后我們實作一個原生窗口應用程序藉由soap來呼叫此web應用程序實作的web service。

 

圖七 實作web service的架構圖

步驟1 – 開發(fā)soap伺服端應用程序

首先程序員可以在delphi中使用soap server application精靈來開發(fā)web service服務器。在delphi 6中我們只需要點選file|new|others菜單,然后點選webservices頁次即可看到下圖的畫面,然后再點選soap server application圖像。

 

圖八 delphi 6的soap server application精靈

在點選了soap server application圖像之后,delphi會詢問程序員要以那一種的實體型態(tài)來實作web service,如下圖所示。程序員可以選擇欲實作的程序型態(tài),例如在這個范例中我選擇以web app debugger executable來實作,因為這個程序型態(tài)可以讓我們在開發(fā)web service時能夠輕易的除錯。當然,程序員也可以選擇以一般的window應用程序來實作web service,而不使用soap server application精靈提供的下列實體型態(tài)的程序。

 

圖九 以delphi 6的web app debugger應用程序的形式開發(fā)web service

在點選了圖九的程序型態(tài)和ok按鈕之后,delphi便會自動幫助程序員產生如下的web模塊。

 

圖十 delphi 6建立建立的web module以及webservices組件

在圖十的web模塊之中,delphi自動產生的thttpsoapdispatcher組件可以讓web server自動呼叫此應用程序,而twsdlhtmlpublish組件則可以自動產生敘述此web service的wsdl內容。


 

圖十一 范例web service的主窗體

現在再讓我們在這個web service程序的主窗體中加入一個tlabel并且設定它的caption特性值為『我的第一個web service』,如上圖所示。

步驟 2 – 定義web service的服務接口并且實作它

接下來的步驟便是真正的實作此web service。首先在delphi 6中建立數據模塊,并且使用dbexpress連結到interbase:

 

圖十二 范例web service的數據模塊,它使用dbexpress組件存取interbase

點選file|new|unit菜單定義如下的imyessays接口,這個接口定義了此web service提供的服務,客戶端應用程序可以呼叫getessaytitles函式取得所有文章的信息,而這些信息是儲存在tessaysinfos的數組中,這個方法展示了delphi 6的web service可以處理復雜的數據型態(tài)。至于getessaycontent則可以根據客戶端傳遞來的文章id而回傳此文章的內容給客戶端應用程序。

unit umyessaysinf;
interface
uses
types, xsbuiltins, uessaysinfo;
type
imyessays = interface(iinvokable)
['{1c8aba87-455b-4430-9881-239f5ffe7f49}']
function getessaytitles : tessaysinfos ; stdcall;
function getessaycontent(const iid : integer) : string; stdcall;
end;
implementation
uses
invokeregistry;
initialization
invregistry.registerinterface(typeinfo(imyessays));
end.

接著我們定義儲存文章信息的數據結構。為了讓文章信息能夠自動傳遞回客戶端,我們可以在delphi 6中從tremotable類別繼承子類別,如此一來delphi 6便會自動幫助我們處理數據marshalling的問題。最后必須呼叫delphi 6提供的remclassregistry對象來注冊這些類別。

unit uessaysinfo;
interface
uses
invokeregistry, xsbuiltins;
type
tessaysinfo = class(tremotable)
private
fessayid : integer;
fessaytitle : widestring;
published
property essaytitle : widestring read fessaytitle write fessaytitle;
property essayid : integer read fessayid write fessayid;
end;

tessaysinfos = array of tessaysinfo;
implementation

initialization
remclassregistry.registerxsclass(tessaysinfo, 'http://www.w3.org/2001/xmlschema', 'tessaysinfo', '',false );
remtyperegistry.registerxsinfo(typeinfo(tessaysinfos), 'http://www.w3.org/2001/xmlschema', 'tessaysinfos');
finalization
remclassregistry.unregisterxsclass(tessaysinfo);
remtyperegistry.unregisterxsinfo(typeinfo(tessaysinfos));
end.

現在到了實作imyessays接口的時候了,我們定義tmyessays類別從tinvokableclass繼承下來并且實作imyessays接口。tinvokableclass類別可以讓客戶端從遠程呼叫。最后同樣呼叫invregistry對象注冊tmyessays類別,以便讓thttpsoapdispatcher組件可以啟動。至于imyessays接口之中的getessaytitles方法則是使用dbexpress從interbase中讀取所有的數據,并且把文章的id和名稱儲存在一個tessaysinfo對象中,再把tessaysinfo對象儲存在tessaysinfos數組中,最后回傳此數組給客戶端。

unit umyessaysimpl;
interface
uses
sysutils, classes, invokeregistry, xsbuiltins, umyessaysinf, uessaysinfo, db, httpprod, udmmyessays, dbxpress;
type
tmyessays = class(tinvokableclass, imyessays)
private
procedure createdatamodule;
procedure freedatamodule;
public
{ iisapitutorials }
function getessaytitles: tessaysinfos; stdcall;
function getessaycontent(const iid : integer) : string; stdcall;
end;
implementation
{ tisapitutorials }

procedure tmyessays.createdatamodule;
begin
dmmyessays := tdmmyessays.create(nil);
end;

procedure tmyessays.freedatamodule;
begin
if (assigned(dmmyessays)) then
begin
dmmyessays.free;
dmmyessays := nil;
end;
end;

function tmyessays.getessaycontent(const iid: integer): string;
begin
result := '尚未實作, 請待續(xù)!!!';
end;

function tmyessays.getessaytitles: tessaysinfos;
var
ino : integer;
iid : integer;
einfo : tessaysinfo;
td: ttransactiondesc;
begin
createdatamodule;

td.transactionid := 1;
td.isolationlevel := xilreadcommitted;
try
dmmyessays.sconnmyessays.starttransaction(td);
ino := dmmyessays.sdsmyessays.recordcount;
setlength(result, ino);
iid := -1;
with dmmyessays.sdsmyessays do
begin
while not eof do
begin
inc(iid);
einfo := tessaysinfo.create;
einfo.essayid := fieldbyname('eid').value;
einfo.essaytitle := fieldbyname('etitle').value;
result[iid] := einfo;
next;
end;
end;
finally
dmmyessays.sconnmyessays.commit(td);
freedatamodule;
end;
end;
initialization
invregistry.registerinvokableclass(tmyessays);
end.

現在這個能夠處理復雜資料的web service便藉由delphi 6提供的webservices組件和精靈完成了,接下來就是開發(fā)客戶端應用程序來呼叫此web service以取得文章信息了。

步驟 3 – 開發(fā)客戶端應用程序呼叫web service

使用delphi 6開發(fā)呼叫web service的客戶端應用程序更簡單,因為delphi 6提供的webservices組件組中的thttprio組件實在是太方便了,我們只要使用對象檢視器設定thttprio組件的wsdllocation特性值為欲呼叫的web service的wsdl,那么thttprio組件便可以自動的處理所有呼叫web service的細節(jié)。

例如下面便是使用delphi 6開發(fā)的客戶端應用程序,在這個應用程序的主窗體上使用了一個thttprio組件,并且在它的wsdllocation特性值中輸入剛才開發(fā)的web service的wsdl檔案的地址。

 

圖十三 范例客戶端應用程序的主窗體

接著在『 我的文章』按鈕的onclick事件處理函式中撰寫如下的程序代碼:

procedure tform2.bitbtn1click(sender: tobject);
var
oricursor : tcursor;
einfos : tessaysinfos;
icount : integer;
lstart, lend : longint;
begin
showcaption;

statusbar1.panels[0].text := '呼叫web service中...';
statusbar1.refresh;
lvmyessays.items.beginupdate;
lvmyessays.items.clear;
oricursor := screen.cursor;
screen.cursor := crhourglass;
lstart := gettickcount;
try
einfos := (httprio1 as imyessays).getessaytitles;
for icount := low(einfos) to high(einfos) do
begin
with lvmyessays.items.add do
begin
caption := einfos[icount].essaytitle;
data := pointer(einfos[icount].essayid);
end;
end;
finally
lend := gettickcount;
showruntime(lstart, lend);
lvmyessays.items.endupdate;
statusbar1.panels[0].text := '完成呼叫web service';
statusbar1.refresh;
screen.cursor := oricursor;
end;
end;

procedure tform2.showcaption;
begin
lblcaption.caption := '太棒了, 我的第一個web service程序';
end;

procedure tform2.showruntime(const lstart, lend: integer);
begin
statusbar1.panels[1].text := floattostr((lend - lstart) / 1000.0) + '秒';
end;

上面的程序代碼藉由thttprio組件呼叫imyessays接口的getessaytitles方法,取得tessaysinfos數組,再從數組中一一的取出每一篇文章的名稱,最后再填入到主窗體中的tlistview組件之中。下圖就是執(zhí)行此客戶端應用程序呼叫web service服務器,并且取得所有文章信息的畫面。從這么簡單的數個步驟中,我們已經使用delphi 6開發(fā)了一個真正的web service應用系統。

 

圖十四 范例客戶端應用程序呼叫web service得到數據的畫面

雖然這是我們使用delphi 6建立的第一個web service,但是這個范例web service展示了delphi 6的soap/web service解決方案能夠輕易的傳遞復雜的數據型態(tài),因為在范例web service中是使用數組的型態(tài)來傳遞所有的文章信息。delphi 6的soap/web service技術絕不是像一些工具只提供簡單的soap/web service解決方案,而是充分的提供了一般和復雜的應用程序,并且能夠整合各種組件模型,是目前最具威力,也是最先進的soap/web service開發(fā)工具之一。

delphi 6除了提供強勁的web service開發(fā)功能之外,新的web app debugger不但可以幫助程序員除錯web應用程序之外,也可以幫助程序員監(jiān)督客戶端應用程序和web service之中傳遞的信息。這些信息包含了soap的封包,以及web service服務器回傳回客戶端的所有soap封包。這對于程序員學習soap和解析soap payload都非常有幫助。例如下圖便是我使用web app debugger檢視此范例web service應用系統傳遞的soap payload。 

圖十五 delphi 6的web app debugger可以顯示客戶端和伺服端之間所有的訊息


為了證明web service的威力和相通性,目前全世界已經有許多人成立了各種web service的網站,讓開發(fā)人員能夠測試web service。例如現在www.xmethods.com便是提供各種web service的網站之一。這個網站羅列了許多的web service,下圖便是這個網站目前提供的web service。

 

圖十六 internet上的xmethods(www.xmethods.com)提供了許多的web service供人呼叫使用

現在讓我們使用delphi 6開發(fā)一個客戶端應用程序來透過internet/intranet呼叫遠程由java實作,執(zhí)行在apache上的一個查詢美國各州氣溫的web service。下圖是這個web service的詳細信息,這個web service的作者甚至提供了java客戶端應用程序展示如何呼叫這個氣溫web service,不過現在我想使用delphi的客戶端應用程序來呼叫,而不是java。


 
圖十七 xmethods上的眾多web service之一,temperature web service

下圖便是在我的機器中使用delphi 6開發(fā)的客戶端應用程序,藉由delphi 6的webservices組件組來呼叫這個位于遠程,我也不知道在什么地方的氣溫web service的結果畫面。

從下圖中可以證明,雖然我并不知道這個web service在那里,我仍然可以藉由web service的標準接口敘述wsdl來使用它,即使它是使用java實作的,并且執(zhí)行在apache之上。


 
圖十八 delphi實作的客戶端應用程序呼叫執(zhí)行在遠程apache上的web service

希望上面的內容可以讓各位讀者了解web service和soap在應用上的潛力以及delphi 6提供的組件技術可以讓開發(fā)人員快速而且輕易的實作出各種威力強大的web service。

也許藉由web service和soap的出現,也會對于目前應用系統架構產生巨大的影響。例如現在『供應鏈』軟件非常的流行,但是許多的供應鏈軟件在整合上,中,下游廠商時,經常會需要所有的廠商使用相同的平臺以及基層軟件。但是對于下游廠商而言,可能無法像上游廠商一樣使用昂貴的設備,例如unix box和大型ERP軟件,許多的下游小廠也許只能使用window nt或是linux平臺。不過現在web service和soap可以提供非常完善的解決方案,就如同下圖顯示的一樣,下游廠商可以只使用asp提供簡單的web service讓他的中游廠商呼叫。而上游廠商則可以在unix box中藉由大型的erp軟件呼叫中游廠商執(zhí)行在window 2000中的biztalk service。如此一來不但每一個廠商都可以選擇最適合的執(zhí)行平臺和軟件,也可以藉由web service和soap整合上,中,下游廠商而提供一個及時且完備的供應鏈。web service和soap正為軟件帶來無限的發(fā)展契機。

 

圖十九 web service的應用架構之一

雖然soap和web service目前已經成為標準并且也已經被世界廠商所接受和支持。但是soap和web service仍然是在成長期,功能規(guī)格仍然在繼續(xù)的改善和強化之中,因此soap和web service的變化也在預期之中。delphi 6實作的soap和web service似乎是比較偏向ibm和java的陣營,因此delphi 6能夠很容易的和java以及php,perl等soap/web service解決方案整合。至于microsoft的soap和web service則稍有不同,需要程序員特別注意一下。
如果下次有時間的話,那么就讓我們繼續(xù)討論microsoft的soap toolkit以及.net之中的soap解決方案,并且比較delphi和它們之間的差異以及如何整合這些不同的soap實作技術。

發(fā)布:2007-03-24 17:59    編輯:泛普軟件 · xiaona    [打印此頁]    [關閉]
相關文章:
上海OA系統
聯系方式

成都公司:成都市成華區(qū)建設南路160號1層9號

重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務大廈18樓

咨詢:400-8352-114

加微信,免費獲取試用系統

QQ在線咨詢