gembin

OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

HBase, Hadoop, ZooKeeper, Cassandra

Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

About Me

 

Java SCA 调用样式[zhuan]

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

posted on 2008-03-12 18:51 gembin 阅读(567) 评论(0)  编辑  收藏 所属分类: SCASOA


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(6)

随笔分类(440)

随笔档案(378)

文章档案(6)

新闻档案(1)

相册

收藏夹(9)

Adobe

Android

AS3

Blog-Links

Build

Design Pattern

Eclipse

Favorite Links

Flickr

Game Dev

HBase

Identity Management

IT resources

JEE

Language

OpenID

OSGi

SOA

Version Control

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

free counters