本文概略介紹了服務組件體系結構(Service Component Architecture,SCA)的傳統 Java
對象(plain old Java object,POJO)組件中的 Java 用法以及傳入傳出 POJO 組件的數據流。您將通過本文了解在
POJO 組件中使用不同調用樣式的效果。
引言
盡管已在相關的課程中說明了 IBM WebSphere Integration Developer 用戶采用 Java 編程所需的每個步驟,但仍然會出現有必要使用 Java 和 POJO 組件的情況。
需
要 POJO 組件的一個重要例子是將僅理解 WSDL 描述的組件的組件與僅能通過 Java 接口進行公開的組件集成時。此外,不能在
WebSphere Integration Developer 的各個向導內操作的數據(如 anyType
類型的數據)可以通過使用服務數據對象(Service Data Object,SDO)API 在 POJO
組件范圍內手動進行處理。這些場景就是相當有意義的用例,說明了對 POJO 的需求。
本文提供了考慮調用樣式以及需要傳入傳出數據的 POJO 組件的 Java 編碼基本知識。但本文并不打算描述所有與 SCA POJO 使用有關的場景。
本文假定您熟悉 SCA 的基本知識,包括模塊和引用的概念。
示例:Hello World
為
了說明此處介紹的概念,我們將首先描述一個簡單的 Hello World 示例。我們的示例是單個 SCA 模塊,名為
HWModule,其中包括兩個 POJO 組件,分別名為 HelloWorld 和 MessageLogger。MessageLogger
將直接向控制臺打印來自 HelloWorld 的消息,并返回有關操作是否成功的信息。圖 1 顯示了描述 MessageLogger 的接口的
WSDL:
圖 1. MessageLogger WSDL 接口
圖 2 顯示了描述 HelloWorld 的接口的 WSDL:
圖 2. HelloWorld WSDL 接口
圖 3 顯示了示例的組裝關系圖:
圖 3. HWModule 組裝關系圖
 |
注意:
讓多個引用指向相同組件通常并不實際,但出于演示目的,我們此處采用了這種做法。 |
|
HelloWorld 使用兩個引用與 MessageLogger 進行交互。一個由 Java 進行類型設置 (j-typed),另一個由 WSDL 進行類型設置 (w-typed),如圖 4 中所示。
圖 4. HelloWorld 引用
圖 5 顯示了 HelloWorld 和 MessageLogger 之間的 HWMessage 業務對象(Business Object,BO):
圖 5. HWMessage BO
此示例的更多細節將在以下各個相應的部分中進行討論。
客戶端 Java 編程模型
本
文重點討論兩種調用樣式:動態調用接口(Dynamic Invocation Interface,DII)和強類型。DII
是一種通用的動態調用模型,所得到的“調用”類型是這樣的:傳入操作名稱,并傳入操作的輸入參數。強類型調用并不會以“調用”告終,而會最終得到一個強類
型調用。
強類型樣式調用
 |
注意:
“j-typed”指引用的接口是由 Java 定義的。 |
|
強類型調用只能在 j-typed 引用上完成。在我們的示例中,我們在已經過 j-typed 的 HelloWorld 上定義了一個名為 MessageLoggerPartner 的引用,如圖 6 中所示。
圖 6. HelloWorld 引用
清單 1 顯示了 HelloWorld 的 sayHello() 方法中的代碼,該方法將以強類型方式調用經過 j-typed 的 MessageLoggerPartner 引用:
清單 1. HelloWorld 的 sayHello() 示例代碼,使用 j-type 引用進行強類型調用
// j-type reference strong-typed usage
MessageLogger service = locateService_MessageLoggerPartner();
Boolean isSuc = service.logMessage(inMsg);
if (isSuc.booleanValue()) { // reuse the inMsg for our response since it's the same type
inMsg.setString("message", "Success");
} else inMsg.setString("message", "Problem consuming message sent");
inMsg.setString("sourceEmail", "service@hw.org");
return inMsg;
|
在
上面的代碼中,您將發現方法 locateService_MessageLoggerPartner() 用于向 MessageLogger
返回一個代理。將為 POJO 組件定義的每個引用生成此方法。在我們的例子中有兩個引用,MessageLoggerPartner 和
MessageLoggerPartner1,因此在 HelloWorld 中生成了兩個方法
locateService_MessageLoggerPartner() 和
locateService_MessageLoggerPartner1()。
DII(弱類型)樣式調用
 |
注意:
“w-typed”指引用的接口是由 WSDL 定義的。
|
|
無論為引用定義的類型如何,都可以進行弱類型調用;不過,如果引用是 w-typed,客戶端將需要使用 DII。
J-typed 引用與 DII
我們也可以采用弱類型方式使用 MessageLoggerPartner 引用。清單 2 顯示了 HelloWorld 的 sayHello() 方法中的代碼,其中采用弱類型方式調用 j-typed 的 MessageLoggerPartner 引用:
清單 2. HelloWorld 的 sayHello() 示例代碼,使用 j-type 引用進行 DII 調用
// j-type reference DII usage
Service service = (Service) locateService_MessageLoggerPartner();
Boolean isSuc = (Boolean) service.invoke("logMessage", inMsg);
if (isSuc.booleanValue()) { // reuse the inMsg for our response since it's the same type
inMsg.setString("message", "Success"); } else
inMsg.setString("message", "Problem consuming message sent");
inMsg.setString("sourceEmail", "service@hw.org");
return inMsg;
|
所有內容都與強類型調用類似,不同的是要向“調用”傳入操作名稱和輸入參數。
W-typed 引用與 DII
如果引用是 w-typed 的,則用戶唯一 可用的調用樣式就是 DII。在我們的示例中,除了 j-typed 引用外 (MessageLoggerPartner),還定義了另一個引用,即已經過 w-typed 的 MessageLoggerPartner1,如圖 7 中所示。
圖 7. HelloWorld 引用
清單 3 顯示了 HelloWorld 的 sayHello() 方法中的代碼,以便采用 DII 方式使用此 w-typed 的 HWMessageLoggerPartner1 引用:
清單 3. HelloWorld 的 sayHello() 示例代碼,使用 w-type 引用進行 DII 調用
// w-type reference DII usage
Service service = (Service) locateService_MessageLoggerPartner1();
BOFactory bof
(BOFactory) new ServiceManager().locateService("com/ibm/websphere/bo/BOFactory");
DataObject inputWrapper =
bof.createByType(service.getReference().getOperationType("logMessage").getInputType());
inputWrapper.setDataObject("inMsg", inMsg);
DataObject outputWrapper = (DataObject) service.invoke("logMessage", inputWrapper);
boolean isSuc = outputWrapper.getBoolean("isSuccessful");
if (isSuc) { // reuse the inMsg for our response since it's the same type
inMsg.setString("message", "Success");
} else inMsg.setString("message", "Problem consuming message sent");
inMsg.setString("sourceEmail", "service@hw.org");
return inMsg;
|
正如可從清單 3 中了解到的,這個場景更為有意義。其中頗有意義的一部分是傳入/傳出調用的輸入類型。
 |
注意:
Doc-literal wrapped (DLW) 是在 WebSphere® Integration Developer 中生成的 WSDL 的默認模式。
|
|
在最后一個場景中,我們將使用與 doc-literal wrapped (DLW) WSDL 中的“wrapper”元素對應的數據對象(inputWrapper 和 outputWrapper)。
因此,為了理解發送何種類型(強類型或弱類型),將需要兩條信息。首先,將需要知道 WSDL 的樣式(DLW 或任何其他樣式),其次,將需要知道引用類型(j-type 或 w-type)。
表 1. 輸入/輸出類型決策表
| j-typed 引用 | w-type 引用 (DLW) | w-type 引用(任何其他樣式) |
弱類型 (DII) |
對于簡單類型,使用 Java 原語;對于復雜類型,使用數據對象 |
WSDL 中為消息指定的 Wrapper 元素,用于封裝有效負載對象:HWMessage 或 Boolean 以及其他諸如此類的內容。消息元素將始終是一個數據對象。 |
為有效負載指定的類型——不過此處并沒有包裝。如果有效負載是復雜類型,則為數據對象;如果是簡單類型,則為 Java 原語。 |
強類型 |
對于簡單類型,使用 Java 原語;對于復雜類型,使用數據對象 |
WSDL 中為消息指定的 Wrapper 元素,用于封裝有效負載對象 HWMessage 或 Boolean 以及其他諸如此類的內容。消息元素將始終是一個數據對象。 |
為有效負載指定的類型——不過此處并沒有包裝。如果有效負載是復雜類型,則為數據對象;如果是簡單類型,則為 Java 原語。 |
常見問題
由于可以采用多種方式調用任何給定的引用,因此可能會遇到一些已知問題。下面將給出其中的常見問題。
ClassCastException 問題
這個常見的錯誤消息指示所接收或發送的數據不是所預期的數據。例如,如果用戶不知道在某些情況下需要包裝,則可能會在對返回對象進行強制轉換時發出此消息。補救方法是更改代碼,以強制轉換為正確的對象。
IllegalArgumentException: Class 'x' does not have a feature named 'y' 問題
這個錯誤消息也指示所接收或發送的數據不是預期的數據,但發生在稍后對數據進行訪問時。例如,接收某個數據對象的用戶可能認為其不是包裝數據對象,并嘗試直接訪問數據。直接訪問此數據將會導致出現錯誤。補救辦法是對代碼進行更改,以訪問正確的屬性。
結束語
這篇短文概略介紹了在 POJO 組件中選擇強調用樣式還是弱調用樣式,并說明了可能出現的兩個常見錯誤,即 ClassCastException 和 IllegalArgumentException。
下載
描述 | 名字 | 大小 | 下載方法 |
Hello World sample project interchange |
ws-soa-sca-java-inv-pi.zip |
13KB |
HTTP |
參考資料
作者簡介
 |
|
 |
Anh-Khoa Phan 在 IBM 的 Rochester Development Lab 擔任軟件工程師。他目前在從事 WebSphere Business Integration 方面的工作。
|
 |
|
 |
Eric
Herness 在 IBM 的 Rochester Development Lab 擔任 Websphere Business
Integration 的首席架構師。他是 WebSphere Foundation Architecture Board
的高級成員,同時也是 Software Group Architecture Board 的核心成員。Eric
研究對象技術和分布式計算中的產品體系結構和產品開發已超過 15 年。
|