公開 Web 服務:WSDL
在線銀行服務由幾種操作構成,在實現這些操作之前,我們將首先介紹一下各操作。您將了解到各操作的細節、消息、端口類型和 WSDL 綁定。
操作
之前已經看到了 在線銀行 Web 服務的概述。現在將了解構建此 Web 服務所需的操作:
Login
- 登錄允許您通過 Web 服務驗證您的憑證,并獲取一個令牌(token),證明您已通過驗證,可進一步進行 Web 服務請求。
- 傳遞兩段數據(用戶名和密碼),返回一段數據(二進制令牌)。
Logout
- 注銷操作將從 Web 服務的經過身份驗證的令牌/用戶名列表中刪除您的令牌和用戶名。
- 注銷僅需您發送令牌,隨后會返回一個確定布爾變量作為響應。
LookupAccounts
- 查找您的賬戶信息。
- 僅需令牌,返回賬戶號、類型和余額列表。
LookupTransactions
- 按日期查找交易。
- 發送令牌和賬戶號,以及可選日期范圍(日期 1 和日期 2),回發一個交易復型數組作為響應(
minOccurs="0" maxOccurs="unbounded"
)。
SearchTransactions
- 按支票號或金額查找交易。
- 允許更為復雜的交易搜索:傳遞賬戶號、令牌,以及支票號范圍或金額范圍,隨后會返回一個滿足條件的交易復型數組作為響應。
TransferFunds
- 將資金從一個賬戶劃撥到另外一個賬戶中。
- 劃撥資金操作要求您發送令牌、源賬戶、目標賬戶號和金額。回發一個確認布爾變量作為響應。
LookupPayees
- 查看與您的在線賬戶相關的收款方。
- 發送令牌,您將接收一個作為響應的收款方別名數組。
AddPayee
- 向您的在線賬戶添加收款方。
- 發送令牌和收款方復型,然后發送一個布爾確認信息作為響應。
EditPayee
- 與
AddPayee
基本完全相同,惟一的差異就是更新收款方而非將其插入基礎數據庫。
ViewPayee
- 查看您的賬戶中與一個收款方相關的所有信息。
- 發送令牌和收款方別名,檢索收款方復型作為響應。
MakeBillPayment
- 支付與一個收款方相關的一份賬單。
- 發送
BillPayment
復型和令牌,回發一個確認布爾變量作為響應。
ChangeBillPayment
- 更改事先安排好的支付。
- 與
MakeBillPayment
基本相同,惟一的差異就是更新支付而非將其插入基本數據庫。
LookupPendingPayments
- 查看所有待定支付。
- 僅發送令牌,您將接收一個
BillPayment
復型數組作為響應。
SubmitLoanApplication
- 提交一份貸款申請表。
- 發送
LoanApplication
復型和令牌,回發一個確認布爾變量作為響應。
ViewLoanApplicationStatus
- 查看與您的在線賬戶相關的所有貸款狀態。
- 僅發送令牌,您將接收一個
LoanApplicationStatus
復型數組。
上邊給出了全部定義。切記,有極多的操作要定義,并且不能過于繁冗或令人感到厭煩。因此,如果您遇到麻煩,可參考本教程后文 下載 一節中給出的 WSDL 文件,將其與上述操作比較。但下面我們會從始至終地詳細介紹部分操作,作為示例供您參考,您可通過這些示例掌握如何處理其他操作。
接下來將定義 WSDL 文件的名稱空間。
名稱空間
盡管最初看上去有些古怪,但您的 WSDL 文件的名稱空間相當重要,因為它們定義了整個 WSDL 中各標記(tag)的上下文。將以下代碼放在已添加到 OnlineBanking.wsdl 文件中的數據結構之前,如 清單 7 所示。
清單 7. 設置 WSDL
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
name="OnlineBanking"
targetNamespace=http://www.example.com/OnlineBanking
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.example.com/OnlineBanking"
xmlns:xsd1="http://www.example.com/OnlineBanking/xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<!-- Types -->
<wsdl:types>
<xsd:schema
targetNamespace="http://www.example.com/OnlineBanking/xsd"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
elementFormDefault="qualified">
|
xsd1:
名稱空間指定 <xsd:schema
標記中定義的所有結構都屬于 xsd1:
名稱空間 (http://www.example.com/OnlineBanking/xsd
),且需要據其引用,與 清單 6 中所引用的 RecurringBillPayment
復型類似。tns
或 targetNamespace
表示頂級 WSDL (http://www.example.com/OnlineBanking
) 中定義的所有消息。接下來將為請求和響應定義元素標記。
請求
本節的剩余內容將引領您為 Login
和 LookupTransactions
操作創建 WSDL。請求為發送至 Web 服務的 SOAP 對象,可包含不同的內部層次結構,如前文中創建的數據結構。在 RecurringBillPayment
復型之后定義登錄請求,如 清單 8 所示。
清單 8. 登錄請求
<xsd:element name="Login">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1"
name="username" type="xsd:string" />
<xsd:element minOccurs="1" maxOccurs="1"
name="password" type="xsd: string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
|
本元素中恰好發送了一個用戶名和密碼。就是這樣。接著定義查找交易元素,如 清單 9 所示。
清單 9. 查找交易請求
<xsd:element name="LookupTransactions">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1"
name="accountNumber" type="xsd:int" />
<xsd:element minOccurs="0" maxOccurs="1"
name="date1" type="xsd:date" />
<xsd:element minOccurs="0" maxOccurs="1"
name="date2" type="xsd:date" />
<xsd:element minOccurs="1" maxOccurs="1"
name="token" type="xsd:base64Binary" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
|
這里有一個接受 accountNumber
和 token
(base64Binary
類型)的查找交易請求。在后文中您將看到 base64Binary
類型在 Java 編程語言中轉換為 byte[]
。下面定義響應。
響應
客戶機創建并發送請求。Web 服務接收請求并根據請求創建響應。定義登錄響應,如 清單 10 所示。
清單 10. 登錄響應
<xsd:element name="LoginResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1"
name="valid" type="xsd:boolean" />
<xsd:element minOccurs="1" maxOccurs="1"
name="token" type="xsd:base64Binary" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
|
登錄成功響應給出有效變量的 true
值及令牌變量中的二進制令牌。再看看查找交易響應。按 清單 11 定義該響應。
清單 11. 查找交易響應
<xsd:element name="LookupTransactionsResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="unbounded"
name="transactions" type="xsd1:Transaction" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
|
該響應返回一個交易元素數組。注意此處使用的 xsd1:
名稱空間。您只需直接為數組類型引用 清單 1 中定義的 Transaction
復型即可。接下來介紹消息。
消息
消息將發送給 Web 服務并返回,這些消息包括 SOAP 請求之前您在 響應 一節中定義的響應。定義 Login
請求和響應消息,如 清單 12 所示。
清單 12. 登錄請求和響應消息
<!-- Messages -->
<wsdl:message name="Login">
<wsdl:part name="parameters" element="xsd1:Login" />
</wsdl:message>
<wsdl:message name="LoginResponse">
<wsdl:part name="parameters" element="xsd1:LoginResponse" />
</wsdl:message>
|
在消息內放置哪些內容作為 <wsdl:part
標記的名稱屬性無關緊要,要注意的項目已用黑體表示。登錄請求消息引用之前定義的 Login
元素,同樣,LoginResponse
響應消息引用之前定義的 LoginResponse
元素。下面定義查找交易請求與響應消息,如 清單 13 所示。
清單 13. 查找交易請求與響應消息
<wsdl:message name="LookupTransactions">
<wsdl:part name="parameters" element="xsd1:LookupTransactions" />
</wsdl:message>
<wsdl:message name="LookupTransactionsResponse">
<wsdl:part name="parameters"
element="xsd1:LookupTransactionsResponse" />
</wsdl:message>
|
現在您應注意到了繁冗重復。就像登錄請求與響應那樣,您要命名查找交易請求和響應,引用之前定義的相關查找交易請求和響應元素。其他請求與響應也遵循同一模板。下面為您的在線銀行 Web 服務定義端口類型。
端口類型
端口類型指定特定 Web 服務的操作。我們將定義端口類型和兩個登錄與查找交易操作。按 清單 14 定義端口類型和登錄操作。
清單 14. 端口類型和登錄操作
<!-- Port type -->
<wsdl:portType name="OnlineBankingPortType">
<wsdl:operation name="Login">
<wsdl: input message="tns:Login" />
<wsdl: output message="tns:LoginResponse" />
</wsdl:operation>
|
首先命名端口類型,在指定 WSDL 綁定時需要用到它。Login
和 LoginResponse
的 tns:
前綴指定應在 tns
名稱空間中查找消息,參見 清單 15 中的定義。現在定義查找交易操作。
清單 15. 查找交易操作
<wsdl:operation name="LookupTransactions">
<wsdl: input message="tns:LookupTransactions" />
<wsdl: output message="tns:LookupTransactionsResponse" />
</wsdl:operation>
|
再一次地,就像 Login
操作那樣,定義 LookupTransactions
操作與之非常類似。接下來介紹 WSDL 綁定。
WSDL 綁定
WSDL 綁定指定消息格式、Web 服務的協議類型、在該端口上公開的操作。定義 WSDL 綁定和登錄操作特有的綁定,如 清單 16 所示。
清單 16. WSDL 登錄操作綁定
<!-- Binding -->
<wsdl:binding name="OnlineBankingPortBinding"
type="tns:OnlineBankingPortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<wsdl:operation name="Login">
<soap:operation
soapAction="http://www.example.com/OnlineBanking/Login"
style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
|
首先,命名綁定。現在注意類型。它引用了您在 清單 14 中定義的端口類型。<soap:binding
標記指定 Web 服務的傳輸方法和方式,分別為 http 和文檔。<soap:body
指定輸入和輸出消息的編碼方式。這里采用文字編碼。接著定義查找交易操作的 WSDL 綁定,如 清單 17 所示。
清單 17. 查找交易操作的 WSDL 綁定
<wsdl:operation name="LookupTransactions">
<soap:operation
soapAction="http://www.example.com/OnlineBanking/LookupTransactions"
style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
|
這又一次與登錄操作具有相似之處。其他操作也遵循這一模板。接下來繼續介紹 WSDL 的最后一部分內容:服務標記。
服務標記
服務標記定義此 Web 服務公開了哪些端口。按 清單 18 進行服務定義。
清單 18. 服務定義
<!-- Service -->
<wsdl:service name="OnlineBankingService">
<wsdl:port name="OnlineBankingPort"
binding="tns:OnlineBankingPortBinding">
<soap:address
location="http://localhost:8080/axis2/services/OnlineBankingService" />
</wsdl:port>
</wsdl:service>
|
首先命名服務,隨后定義一個公開的端口 OnlineBankingPort
,該端口引用您在 清單 17 中所定義的 WSDL 綁定。地址用于指定 Geronimo 上查找 Web 服務的 URL,也是收發 SOAP 請求的 URL。
下一節將 WSDL 編譯為 Java 代碼并在 Geronimo 上進行部署。
編譯與部署 Web 服務
現在開始創建 Java 代碼,它將實現在 WSDL 中定義的 Web 服務并使用 Axis2 在 Geronimo 上進行部署。
WSDL2Java
為創建 Web 服務的 Java 實現,請在您的 WSDL 文件上運行 WSDL2Java 工具。為此,鍵入以下代碼(在 Microsoft? Windows? 中):
<axis2-binary-install-dir>/bin/WSDL2Java -d xmlbeans -uri ask.wsdl
-p com.ibm.axis2.onlinebanking -ss -sd
或(在 Linux? 中):
sh <axis2-binary-install-dir>/bin/WSDL2Java.sh -d xmlbeans
-uri ask.wsdl -p com.ibm.axis2.onlinebanking -sd
現在鍵入以下代碼以創建用于測試的客戶機存根(在 Windows 中):
<axis2-binary-install-dir>/bin/WSDL2Java -d xmlbeans -uri ask.wsdl
-p com.ibm.axis2.onlinebanking -ss -sd
或(在 Linux 中):
sh <axis2-binary-install-dir>/bin/WSDL2Java.sh -d xmlbeans
-uri ask.wsdl -p com.ibm.axis2.onlinebanking -sd
就是這樣!現在 ./src 目錄下應已創建好了 Java 源文件。方便的 Apache Ant build.xml 文件也會創建在此目錄中。現在填充基本 Web 服務框架。
填充框架
為避免在測試 Web 服務時出現嚴重錯誤,需要在填充 Web 服務框架時使其永遠不會返回 null
。查看 ./src/com/ibm/axis2/onlinebanking/OnlineBankingPortTypeSkeleton.java 這一 Web 服務框架。打開并仔細觀察該框架。您應注意到其中某處的 Login
方法,如 清單 19 所示。
清單 19. 原始 Web 服務
public com.example.www.onlinebanking.xsd.LoginResponseDocument Login
(com.example.www.onlinebanking.xsd.
LoginDocument param8 ){
//Todo fill this with the necessary business logic
return null;
}
|
注意返回類型為 LoginResponseDocument
,方法的參數為 LoginDocument
(請求)。通過返回一個空的 LoginResponseDocument
填充示例定義,如 清單 20 所示。
清單 20. 示例定義
public com.example.www.onlinebanking.xsd.
LoginResponseDocument Login
(com.example.www.onlinebanking.xsd.LoginDocument param8 ){
LoginDocument.
Login req =
param8.getLogin();
LoginResponseDocument res =
LoginResponseDocument.Factory.newInstance();
LoginResponseDocument.
LoginResponse res2 =
res.addNewLoginResponse();
return res;
}
|
在第一行中,從 param8
中獲得實際 Login
請求對象(Axis2 在您的系統中生成的名稱可能與此不同)。接下來在第三行中創建一個新的 LoginResponseDocument
,添加新的 LoginResponse
,返回空 res
對象 —— LoginResponseDocument
。
另外,不要忘記在頂端的包聲明之下輸入以下 import
語句:
package com.ibm.axis2.onlinebanking;
import com.example.www.onlinebanking.xsd.*;
...
這樣在構建和部署 Web 服務時就不會遇到 class not found
錯誤了。
在 Geronimo 上部署 Axis2 和 Web 服務
首先,您需要構建 Web 服務。進入運行 WSDL2Java 工具的目錄下,鍵入:
ant jar.server
這將創建一個 OnlineBankingService.aar 文件,路徑為 ./build/lib/OnlineBankingService.aar。啟動 Geronimo,部署此 Web 服務 Axis2 歸檔文件。鍵入以下命令引導 Apache Geronimo:
java -jar <geronimo-install-dir>/bin/server.jar
您已通過將 axis2.war 文件復制到 <geronimo-install-dir>/deploy 中而從 Apache 處下載了此文件,下面來部署此文件。打開瀏覽器,轉到 http://localhost:8080/axis2/Login.jsp。
以用戶名 admin、密碼 axis2 登錄。將您的瀏覽器轉到 http://localhost:8080/axis2/upload.jsp。
單擊 Browse,找到 OnlineBankingService.aar 文件,然后單擊 Upload。在 20 到 30 秒內即可準備好 Web 服務。同時,下一節將為您介紹如何創建一個簡單的客戶機,以測試 Web 服務的初始功能。
創建和測試簡單的客戶機
為測試您的 Web 服務,應定義一個簡單的客戶機對其進行徹底的測試,確保正確傳輸 SOAP 消息。
導入類依賴性
創建客戶機的第一步是導入類依賴性。創建 Client.java 文件,路徑為 ./src/Client.java。按 清單 21 定義此文件。
清單 21. 導入類依賴性
import com.example.www.onlinebanking.xsd.*;
import com.ibm.axis2.onlinebanking.*;
import java.util.*;
public class Client{
public static void main(java.lang.String args[]){
|
您將使用的絕大多數對象都在前兩個導入語句中,特別是客戶機存根,還有請求與響應對象,以及 數據結構 一節中所定義的其他數據結構。下面開始定義主函數,首先聲明客戶機存根。
創建客戶機存根
客戶機存根使您可處理現運行于 Geronimo 之上的 Web 服務。按 清單 22 創建客戶機存根。
清單 22. 客戶機存根
public static void main(java.lang.String args[]){
OnlineBankingPortTypeStub stub = null;
try{
stub = new OnlineBankingPortTypeStub(null,
"http://localhost:8080/axis2/services/OnlineBankingService");
...
} catch(Exception e){
e.printStackTrace();
}
}
|
將 Web 服務的 URL 傳遞給 OnlineBankingPortTypeStub
對象即可輕松完成對象的初始化。下面創建一些在調用和測試 Web 服務時使用的初始函數。
調用 Web 服務
本節內容也存在著重復的現象,因此這里只為您介紹在 Web 服務中調用 Login
和 LookupTransactions
操作的 API。掌握這種模板和 清單 25 中定義的函數調用后,即可輕松處理其余部分。首先定義調用 Login
操作的方法,如 清單 23 所示。
清單 23. 調用 Login 操作
/* LOGIN */
public static byte[] login(OnlineBankingPortTypeStub stub,
String username, String password){
try{
LoginDocument reqDoc00 = LoginDocument.
Factory.newInstance();
LoginDocument.Login reqDoc01 = reqDoc00.addNewLogin();
LoginResponseDocument resDoc00 = stub.Login(reqDoc00);
LoginResponseDocument.LoginResponse resDoc01 =
resDoc00.getLoginResponse();
return null;
} catch(Exception e){
e.printStackTrace();
}
System.out.println("Authorization failed");
return null;
}
|
在這里,我們輕松地創建了一個空的 LoginDocument
請求、將其發送給 Web 服務,然后接收一個空對象。如果一切順利,則不會出現任何錯誤。清單 24 顯示了定義 LookupTransactions
操作的原理示例。
清單 24. 調用 LookupTransactions 操作
/* LOOKUPTRANSACTIONS */
public static boolean lookupTransactions(OnlineBankingPortTypeStub
stub){
try{
LookupTransactionsDocument reqDoc00 =
LookupTransactionsDocument.Factory.newInstance();
LookupTransactionsDocument.
LookupTransactions reqDoc01 =
reqDoc00.addNewLookupTransactions();
LookupTransactionsResponseDocument resDoc00 =
stub.LookupTransactions(reqDoc00);
LookupTransactionsResponseDocument.
LookupTransactionsResponse resDoc01 =
resDoc00.getLookupTransactionsResponse();
return true;
} catch(Exception e){
e.printStackTrace();
}
return false;
}
|
為其他所有操作創建類似的模板,這樣您就可以對它們進行測試,為順利學習本系列教程的第 2 部分作好準備。接下來一次性測試所有 Web 服務操作,調用方法(參見 清單 25)。
清單 25. 一次性測試所有 Web 服務操作
...
login(stub);
lookupAccounts(stub);
lookupTransactions(stub);
searchTransactions(stub);
viewPayee(stub);
makeBillPayment(stub);
changeBillPayment(stub);
lookupPendingPayments(stub);
addPayee(stub);
lookupPayees(stub);
editPayee(stub);
transferFunds(stub);
submitLoanApplication(stub);
viewLoanApplicationStatus(stub);
logout(stub);
} catch(Exception e){
e.printStackTrace();
}
}
|
調用各方法,傳入存根,這樣就作好了準備,可以構建并運行客戶機了。
構建客戶機,測試 Web 服務
您應該希望再次構建 Web 服務。像之前一樣,鍵入以下命令來構建它:
ant jar.server
要運行客戶機,向 build.xml 文件中添加一個新的 Ant 任務,如 清單 26 所示。
清單 26. 添加新 Ant 任務以運行客戶機
<!-- new target for running the client -->
<target depends="jar.server" name="run.client">
<java classname="Client" fork="true">
<classpath>
<path refid="axis2.class.path"/>
<path location="${lib}/${name}.aar"/>
<path location="${lib}/${xbeans.packaged.jar.name}"/>
</classpath>
</java>
</target>
|
這樣就創建好了一個運行客戶機的新任務,鍵入以下命令即可運行客戶機:
ant run.client
您應看到運行客戶機的控制臺輸出,如 圖 1 所示。
圖 1. 運行客戶機
服務器控制臺輸出(也就是運行 Geronimo 的控制臺)應如 圖 2 所示。
圖 2. 服務器輸出
此時,您或許會注意到,首次運行客戶機要花費很長時間,這是因為 Web 服務需要在您的機器上加載并緩存自己。此后再運行客戶機會快很多,您會注意到明顯的速度提高。
至此,一切都很好!Web 服務正常運轉了!
posted on 2006-12-29 19:40
SIMONE 閱讀(1521)
評論(0) 編輯 收藏 所屬分類:
AXIS 、
JAVA