IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  SOA and Web services | Java technology  >

Java SCA 调用样式

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

样例代码


级别: 中级

Anh-Khoa Phan (anhkhoa@us.ibm.com), 软件工程师, IBM
Eric Herness (herness@us.ibm.com), WebSphere Business Integration 首席架构师, IBM

2006 年 9 月 05 日

本文概略介绍了服务组件体系结构(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 接口
MessageLogger WSDL 接口

图 2 显示了描述 HelloWorld 的接口的 WSDL:


图 2. HelloWorld WSDL 接口
HelloWorld WSDL 接口

图 3 显示了示例的组装关系图:


图 3. HWModule 组装关系图
HWModule 组装关系图
注意:
让多个引用指向相同组件通常并不实际,但出于演示目的,我们此处采用了这种做法。

HelloWorld 使用两个引用与 MessageLogger 进行交互。一个由 Java 进行类型设置 (j-typed),另一个由 WSDL 进行类型设置 (w-typed),如图 4 中所示。


图 4. HelloWorld 引用
HelloWorld 引用

图 5 显示了 HelloWorld 和 MessageLogger 之间的 HWMessage 业务对象(Business Object,BO):


图 5. HWMessage BO
HWMessage BO

此示例的更多细节将在以下各个相应的部分中进行讨论。





回页首


客户端 Java 编程模型

本文重点讨论两种调用样式:动态调用接口(Dynamic Invocation Interface,DII)和强类型。DII 是一种通用的动态调用模型,所得到的“调用”类型是这样的:传入操作名称,并传入操作的输入参数。强类型调用并不会以“调用”告终,而会最终得到一个强类型调用。

强类型样式调用

注意:
“j-typed”指引用的接口是由 Java 定义的。

强类型调用只能在 j-typed 引用上完成。在我们的示例中,我们在已经过 j-typed 的 HelloWorld 上定义了一个名为 MessageLoggerPartner 的引用,如图 6 中所示。


图 6. HelloWorld 引用
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 引用
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 interchangews-soa-sca-java-inv-pi.zip13KBHTTP
关于下载方法的信息


参考资料



作者简介

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 年。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款