在Visual FoxPro中建立Web服務
注:該文章節選自作者的《Visual FoxPro程式設計參考手冊》
建立一個Web服務是一個複雜的過程,這涉及到要使用Internet資訊服務(IIS)、Visual FoxPro COM服務程式和簡單對象通路協定(SOAP)。在這節中将結合上節中介紹的XMLAdapter和在20.4節中介紹的CursorAdapter來建立一個可以通過HTTP進行擷取和修改SQL Server 2000附帶示例資料庫Northwind中Customers表的Web服務執行個體。該Web服務的流程圖18-11所示。可以看出,這是一個3層架構的客戶/伺服器模式。

<shapetype id="_x0000_t75" stroked="f" filled="f" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 332.25pt; HEIGHT: 38.25pt" type="#_x0000_t75"><imagedata o:title="18-11" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.png"></imagedata></shape>
圖18-11 Web服務流程圖
18.4.1 建立COM服務程式
建立Web服務,首先要建立一個COM服務程式,然後才可以使用Visual FoxPro的Web服務釋出向導将COM升遷為Web服務。
1.建立項目和類
建立一個名為MyWebService的項目,然後在項目中使用以下代碼建立一個叫做MyClass的.prg檔案,在其中建立了一個ChangeCustomer類。
DEFINE CLASS <place w:st="on"><city w:st="on">ChangeCustomer</city><state w:st="on">AS</state></place> Session OLEPUBLIC
DataSession=2 &&私有資料工作期
PROCEDURE Init
SET MULTILOCKS ON
ENDPROC
PROCEDURE GetCustomerInfo HelpString "擷取客戶資訊"
LOCAL oXMLAdapter AS XMLAdapter,oCA AS String,cXML AS String
oCA=CREATEOBJECT("MyCursorAdapter") &&建立CursorAdapter對象
oCA.CursorFill() &&按oCA的Alias屬性指定的名稱生成臨時表
oXMLAdapter=NEWOBJECT("XMLAdapter") &&建立XMLAdapter
oXMLAdapter.AddTableSchema(oCA.Alias) &&加載臨時表到XMLAdapter對象
oXMLAdapter.ToXML("cXML") &&生成XML字元串
RELEASE oXMLAdapter,oCA &&釋放對象執行個體
RETURN cXML &&傳回XML字元串
ENDPROC
PROCEDURE UpdateCustomer(cXML AS String) HelpString "更新客戶資訊"
LOCAL oXMLAdapter AS XMLAdapter,oCA AS CursorAdapter
oXMLAdapter=NEWOBJECT("XMLAdapter") &&建立XMLAdapter
oXMLAdapter.UTF8Encoded=.F.
oXMLAdapter.IsDiffGram=.T.
oXMLAdapter.LoadXML(cXML,.F.) &&加載XML
oCA=CREATEOBJECT("MyCursorAdapter")
oXMLAdapter.Tables(1).ChangesToCursor(oCA.Alias) &&還原緩沖表
oCA.CursorAttach(oCA.Alias) &&将還原出的緩沖表與CursorAdapter建立關聯
=TABLEUPDATE(.T.) &&發送更新
RELEASE oXMLAdapter,oCA
ENDPROC
PROCEDURE Error(nError AS Integer,cMethod AS String,nLine AS Integer)
LOCAL cText AS String
cText=cMethod+" 錯誤号="+LTRIM(STR(nError,5))+" 行号="+LTRIM(STR(nLine,8))+" "+MESSAGE()
COMRETURNERROR(cText,_VFP.ServerName)
ENDPROC
ENDDEFINE
*!* 建立基于CursorAdapter的子類,用于連接配接到SQL Server
DEFINE CLASS <place w:st="on"><city w:st="on">MyCursorAdapter</city><state w:st="on">AS</state></place> CursorAdapter
Alias="Customer"
BreakOnError= .F.
DataSourceType="ODBC"
Tables="Customers"
SendUpdates=.T.
AllowDelete=.T.
AllowInsert=.T.
AllowUpdate=.T.
UpdateType=1 &&發送更新方式為UPDATE
WhereType=1 &&Where子句類型為僅由KeyFieldList屬性指定的主關鍵字段組成
KeyFieldList="CustomerID"
UpdatableFieldList="CustomerID, CompanyName"
UpdateNameList="CustomerID Customers.CustomerID, CompanyName Customers.CompanyName"
BufferModeOverride= 5 &&開放式表緩存
cConnectionString="Driver={SQL Server};Server=localhost;Uid=sa;Pwd=;Database=northwind"
PROCEDURE Init &&類執行個體化時直接建立連接配接
This.DataSource=SQLSTRINGCONNECT(This.cConnectionString, .T.)
This.SelectCmd="SELECT CustomerID, CompanyName FROM Customers"
This.CursorSchema ="CustomerID C(5), CompanyName C(40)"
ENDPROC
FUNCTION Destroy() &&在釋放對象時斷開與SQL Server的連接配接
SQLDISCONNECT(This.DataSource)
ENDFUNC
ENDDEFINE
上面代碼中的GetCustomerInfo( )方法用于将Customers的CustomerID和CompanyName字段中的所有内容以XML格式傳回給用戶端;UpdateCustomer( )方法根據用戶端發送來的Diffgrams格式的XML更新到Customers表。
2.編譯項目為COM服務程式
在17.4.2節中詳細介紹了編譯COM對象的方法與原理,是以這裡隻簡單介紹步驟。在正式編譯前,需要預編譯一下自動服務程式,才可以設定自動服務程式的項目資訊。單擊項目管理器的Build(編譯)指令按鈕,打開Build Options(編譯選項)對話框,選擇Multi-threaded COM server(多線程COM服務程式)選項進行連遍,編譯成功後,該COM元件自動在本地計算機的Windows中注冊并可用。
在項目管理器上單擊滑鼠右鍵,在彈出的快捷菜單上選擇Project Info(項目資訊)菜單項,打開如圖18-12所示Project Information對話框,在Servers頁籤的Instancing(執行個體)下拉清單中選擇服務類型為Multi Use(多重使用)。
單擊項目管理器中的Build按鈕重新連編項目為Multi-threaded COM server。
18.4.2 安裝并配置Internet資訊服務(IIS)
要在伺服器上釋出Web服務,需要IIS的支援。IIS在Windows XP中是作為可選元件提供的,可以在Windows的控制台中輕按兩下“添加或删除程式”圖示打開“Windows元件向導”對話框,在元件清單中複選“Internet資訊服務(IIS)”元件,并單擊“下一步”按鈕進行安裝,如圖18-13所示。安裝成功後,可以打開Internet Explorer浏覽器,在位址欄中輸入“http://127.0.0.1”,可打開預設的站點頁面。
<shape id="_x0000_i1026" style="WIDTH: 187.5pt; HEIGHT: 151.5pt" type="#_x0000_t75"><imagedata o:title="18-10" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image003.jpg"></imagedata></shape>
<shape id="_x0000_i1027" style="WIDTH: 200.25pt; HEIGHT: 153pt" type="#_x0000_t75"><imagedata o:title="18-11" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image005.jpg"></imagedata></shape>
圖18-12 設定服務類型
圖18-13 添加IIS元件
在安裝好IIS後,應該為要釋出的Web服務建立一個虛拟目錄,以友善調用,步驟如下:
(1)在控制台中輕按兩下“管理工具”圖示,打開“管理工具”視窗。
(2)在“管理工具”視窗中輕按兩下“Internet資訊服務”圖示,打開“Internet資訊服務”視窗,如圖18-14所示。
(3)在“預設站點”節點上單擊滑鼠右鍵,在出現的快捷菜單中,選擇“建立”菜單項下的“虛拟目錄”選項,打開“虛拟目錄建立向導”對話框,如圖18-15所示。
(4)單擊“下一步”按鈕,在出現的如圖18-16所示的“别名”文本框中為虛拟目錄指定一個名稱“FoxWebService”,通過該名稱可以引用一個硬碟上的實際實體目錄。
(5)單擊“下一步”按鈕,在出現的如圖18-17所示的“目錄”文本框中指定一個存放Web服務内容的實際實體目錄。
(6)單擊“下一步”按鈕,将出現如圖18-18所示的設定目錄權限畫面,如圖設定後,單擊“下一步”按鈕,在出現的畫面中單擊“完成”按鈕,虛拟目錄将被成功建立到“預設網站”節點中,如圖18-19所示。
<shape id="_x0000_i1028" style="WIDTH: 194.25pt; HEIGHT: 152.25pt" type="#_x0000_t75"><imagedata o:title="18-12" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image007.jpg"></imagedata></shape>
<shape id="_x0000_i1029" style="WIDTH: 193.5pt; HEIGHT: 141.75pt" type="#_x0000_t75"><imagedata o:title="18-13" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image009.jpg"></imagedata></shape>
圖18-14 “Internet資訊服務”視窗
圖18-15 “虛拟目錄建立向導”對話框
<shape id="_x0000_i1030" style="WIDTH: 193.5pt; HEIGHT: 141pt" type="#_x0000_t75"><imagedata o:title="18-14" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image011.jpg"></imagedata></shape>
<shape id="_x0000_i1031" style="WIDTH: 193.5pt; HEIGHT: 141.75pt" type="#_x0000_t75"><imagedata o:title="18-15" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image013.jpg"></imagedata></shape>
圖18-16 建立虛拟目錄别名
圖18-17 設定實體目錄
<shape id="_x0000_i1032" style="WIDTH: 193.5pt; HEIGHT: 141.75pt" type="#_x0000_t75"><imagedata o:title="18-16" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image015.jpg"></imagedata></shape>
<shape id="_x0000_i1033" style="WIDTH: 195pt; HEIGHT: 152.25pt" type="#_x0000_t75"><imagedata o:title="18-17" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image017.jpg"></imagedata></shape>
圖18-18 設定目錄權限
圖18-19 虛拟目錄添加完成後
18.4.3 建立并釋出Web服務
可以使用Visual FoxPro的Web Service向導來建立和釋出Web服務,步驟如下:
(1)選擇Visual FoxPro Tools菜單中Wizards菜單項下的Web Service子菜單項,打開XML Web Services Publisher(Web服務釋出器)對話框,如圖18-20所示。在COM Server(COM服務程式)下拉選項框中選擇要釋出的.dll元件,如果元件沒有包含在清單中,可以單擊後面的省略(…)按鈕進行選取。
(2)單擊對話框中的Advanced(進階)按鈕打開如圖18-21所示的XML Web Service Location(Web服務位置)對話框,在Select Location下拉選擇要釋出的虛拟目錄位置。
<shape id="_x0000_i1034" style="WIDTH: 178.5pt; HEIGHT: 75pt" type="#_x0000_t75"><imagedata o:title="18-18" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image019.jpg"></imagedata></shape>
<shape id="_x0000_i1035" style="WIDTH: 218.25pt; HEIGHT: 108pt" type="#_x0000_t75"><imagedata o:title="18-19" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image021.jpg"></imagedata></shape>
圖18-20 XML Web Services Publisher對話框
圖18-21 XML Web Service Location對話框
(3)虛拟目錄選擇正确後,單擊圖18-21中的Select(選擇)按鈕,将打開可對Web服務的Options(選項)、Methods(方法)和Namespaces(命名空間)進行設定的對話框。具體設定分别如圖18-22、圖18-23、圖18-24所示。完成後單擊OK按鈕傳回到如圖18-20所示的對話框。
(4)單擊圖18-20所示的Generate(生成)按鈕将建立并釋出Web服務,在Visual FoxPro生成Web服務的檔案後,出現Web服務釋出結果對話框,顯示一個包含COM server、.WSDL檔案、ISAPI或ASP 偵聽的編譯結果清單。如圖18-25所示。
<shape id="_x0000_i1036" style="WIDTH: 185.25pt; HEIGHT: 166.5pt" type="#_x0000_t75"><imagedata o:title="18-20" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image023.jpg"></imagedata></shape>
<shape id="_x0000_i1037" style="WIDTH: 185.25pt; HEIGHT: 166.5pt" type="#_x0000_t75"><imagedata o:title="18-21" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image025.jpg"></imagedata></shape>
圖18-22 設定Web服務選項
圖18-23 設定Web服務支援的方法
<shape id="_x0000_i1038" style="WIDTH: 185.25pt; HEIGHT: 166.5pt" type="#_x0000_t75"><imagedata o:title="18-22" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image027.jpg"></imagedata></shape>
<shape id="_x0000_i1039" style="WIDTH: 190.5pt; HEIGHT: 102.75pt" type="#_x0000_t75"><imagedata o:title="18-23" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image029.jpg"></imagedata></shape>
圖18-24 設定Web服務的命名空間
圖18-25 Web服務釋出結果
在Web服務釋出成功後,将在圖18-21的File Output Path(檔案輸出路徑)文本框中指定的目錄中生成3個檔案(2個.wsml檔案和一個.wsdl檔案),在該示例中,所生成的檔案是ChangeCustomer.WSDL、ChangeCustomer.wsml和ChangeCustomerClient.wsml。這3個檔案都是XML檔案,可以直接在浏覽器或文本編輯器中檢視。
18.4.4 在IntelliSense中注冊Web服務
當在IntelliSense中注冊Web服務後,在書寫有關已注冊Web服務的程式代碼時,IntelliSense可以随時進行代碼輸入提示。注冊步驟如下:
(1)選擇Visual FoxPro Tools菜單下的IntelliSense Manager菜單項,打開IntelliSense Manager視窗,如圖18-26所示。
(2)單擊Type頁框中的Web Services按鈕,在打開的對話框的WSDL URL Location(WSDL URL位置)文本框中輸入所建立WSDL檔案的URL,如圖18-27所示。然後單擊Register按鈕進行注冊。
<shape id="_x0000_i1040" style="WIDTH: 180.75pt; HEIGHT: 131.25pt" type="#_x0000_t75"><imagedata o:title="18-24" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image031.jpg"></imagedata></shape>
<shape id="_x0000_i1041" style="WIDTH: 207pt; HEIGHT: 82.5pt" type="#_x0000_t75"><imagedata o:title="18-25" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image033.jpg"></imagedata></shape>
圖18-26 IntelliSense Manager視窗
圖18-27 指定WSDL URL并注冊Web服務
18.4.5 使用Web服務
1.SoapClient30對象
在Visual FoxPro中可以通過SoapClient30對象調用Web服務,SoapClient30對象為用戶端提供了一種通過SOAP協定發送請求到伺服器端并處理伺服器應答的進階接口。其使用方法如下:
oSoapClient=CREATEOBJECT("MSSOAP.SoapClient30") &&建立對象
在建立SoapClient30對象後,應該使用對象的MSSoapInit( )方法來初始化對象,在初始化期間,所有可在認證伺服器(認證伺服器在WSDL檔案中指定)上的指定的操作将綁定SoapClient30對象,是以,這時就可以使用SoapClient30對象調用在伺服器中定義的操作了。MSSoapInit( )方法的文法格式如下:
oSoapClient.MSSoapInit(WSDLFile,ServiceName,Port,WSMLFile)
參數說明如下:
WSDLFile
字元型。該參數是WSDL檔案的URL,用于描述由伺服器提供的服務,或者是包含在WSDL檔案中的一個字元串。如果該參數的第一個字元是“<”,表示該參數值是一個WSDL字元串;否則,表示該參數值是一個WSDL檔案。
ServiceName
字元型。可選的。該參數是在WDSL檔案中的服務。如果忽略該參數、或為NULL、或為空字元串(""),在初始化SoapClient30對象時,則使用在WSDL檔案中指定的第一個服務。
Port
字元型。可選的。該參數是在WSDL檔案的端口名稱,用來包含在SOAP請求資訊中的指定操作。如果忽略該參數、或為NULL、或為空字元串(""),在初始化SoapClient30對象時,則使用在WSDL檔案中指定的第一個端口。
WSMLFile
字元型。可選的。該參數是WSML檔案的URL,在使用自定義類型映射程式時,該參數是必須的。
現在的問題是如何獲得這些參數名稱?使用浏覽器或其他文本編輯器中打開所生成的WSDL檔案,如圖18-28所示。其中的service元素便是服務的名稱,port元素是端口名稱。
<shape id="_x0000_i1042" style="WIDTH: 337.5pt; HEIGHT: 40.5pt" type="#_x0000_t75"><imagedata o:title="18-26" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image035.jpg"></imagedata></shape>
圖18-28 ChangeCustomer.WSDL檔案片段
由于在該示例中隻建立了一個服務,是以,可以隻指定WSDLFile即可。例如,下面的語句可以Web服務調用在COM元件中的GetCustomerInfo( )方法來獲得Customers表中資料。
oSoapClient=CREATEOBJECT("MSSOAP.SoapClient30")
oSoapClient.MSSoapInit("http://CCB-ZHJ/FoxWebService/ChangeCustomer.WSDL") &&初始化SoapClient30對象
cXML=oSoapClient.GetCustomerInfo() &&獲得XML格式的Customers表中的資料
?cXML
2.應用示例
建立一個如圖18-29所示的表單。在“讀取資料”按鈕的Click事件中加入下列代碼,用于從SQL Server資料庫中讀取資訊,并在表格Grid1中顯示出來。
oSoapClient=CREATEOBJECT("MSSOAP.SoapClient30")
oSoapClient.MSSoapInit("http://CCB-ZHJ/FoxWebService/ChangeCustomer.WSDL")
cXML=oSoapClient.GetCustomerInfo() &&獲得XML格式的Customers表中的資料
RELEASE oSoapClient
SET MULTILOCKS ON
IF USED("curCustomer") &&關閉表
USE IN curCustomer
ENDIF
*!* 将XML轉換為臨時表
oXMLAdapter=CREATEOBJECT("XMLAdapter")
oXMLAdapter.LoadXML(cXML,.F.)
oXMLAdapter.Tables(1).Alias="curCustomer"
oXMLAdapter.Tables(1).ToCursor()
SELECT curCustomer
=CURSORSETPROP("Buffering",5)
*!* 設定表格
WITH Thisform.Grid1
.RecordSourceType=1
.RecordSource="curCustomer"
.ColumnCount=2
.Columns(1).Header1.Caption="客戶編号"
.Columns(1).ControlSource="curCustomer.CustomerID"
.Columns(1).Width=80
.Columns(2).Header1.Caption="公司名稱"
.Columns(2).ControlSource="curCustomer.CompanyName"
.Columns(2).Width=200
ENDWITH
Thisform.Refresh
在“發送更新”按鈕的Click事件中加入下列代碼,用于将Grid1中經過編輯的資料發送到SQL Server伺服器并更新資料。
*!* 生成Diffgrams格式的XML文檔