用WSIF实现EAI

时间:2022-10-16 06:54:55

Web服务调用框架(WSIF)不需要修改或者扩展BPEL(业务流程执行语言)代码就能实现与J2EE工件的链接,从而实现企业应用集成。

在实际情况下,业务流程执行语言(BPEL)往往必须连接到现有的应用程序或者系统才能实现系统集成。而本文着重讨论的是如何连接到J2EE工件,譬如Java类、Enterprise JavaBean(EJB)、Java消息服务(JMS)、可通过 Java连接器架构(JCA)访问的企业资源规划系统、Java数据库连接性(JDBC)数据库或者其他Java资源。

虽然可以把这些资源转换成Web服务实现集成,但这种做法存在几个缺点: 调用Web服务操作的性能开销要比调用原生Java类的开销大好几个数量级,并且比调用EJB或者其他原生Java资源大一个数量级。另外,Web服务调用缺乏在事务执行期间传送上下文的重要功能。相比之下,如果直接使用Java资源,事务上下文就可以自动传送,但前提是Java资源提供这种支持(譬如EJB和JCA就提供这种支持)。

因此,比较好的做法就是以原生方式访问这些外部资源。原生连接到Java资源并不是 BPEL的一项标准特性,但Oracle BPEL流程管理器(Oracle BPEL Process Manager)提供了一种解决方案: Web服务调用框架(WSIF),它不需要修改或者扩展BPEL代码。这项功能大大扩展了BPEL的应用范围,并且使它适用于企业应用集成(EAI)。

了解WSIF

以购买图书的业务流程为例。这个异步流程有三个Web服务: 图书等级Web服务,返回从0到5(最好)的某本图书的等级; 用于两个相同书店服务的Web服务各一个,返回图书价格。该流程选择较低的价格,然后购买图书。本示例定义了故障处理程序,该流程则被分成了多个作用域(Check 1_BuyBook\BuyBook.bpel)。

假设为了获得图书等级,你偏爱使用Java类、EJB(会话bean)、可通过 JCA 访问的企业信息系统中的服务,或者类似的Java资源。要使用Oracle BPEL流程管理器把这些资源(可能还包括存在绑定的其他任何资源)集成到BPEL流程中,只要修改服务绑定 (WSDL),而不是修改BPEL流程本身。因此,想使用Java类取代图书等级Web服务,只要修改该Web服务的WSDL即可。

WSIF最初是由IBM alphaWorks开发的一项Apache技术,作为其Web服务工具包的一部分。正是这项底层技术让实现这种方法成为可能。即使WSIF不是通过SOAP来进行联系的Web服务,它仍然可以让开发人员用WSDL来描述Web服务,从而扩展Web服务模型。WSIF 还可以把这样的服务映射到实际的实现和协议。

换句话说,可以把BPEL流程所用的任何合作伙伴Web服务的抽象描述绑定到相应资源上,这些资源可以使用其中一种得到支持的WSIF绑定来进行联系。Oracle BPEL流程管理器10.1.2使用的WSIF支持Java类、EJB、JCA、HTTP GET与POST以及套接字; 还可以定义定制的WSIF绑定,使用来自BPEL的几乎任何资源。

这种方法使得BPEL对EAI和B2B而言非常有用。企业信息系统通常包括许多不同的软件部分,譬如可通过JCA访问的遗留应用程序、EJB以及在不同平台上开发的Web服务等。要把所有这些部分集成起来,就要应对不同协议。譬如说,如果软件迁移到不同服务器上,或者经升级后需要使用一种新技术,就得升级集成代码――除非使用WSIF。

WSIF还有其他重要好处: 通过WSIF调用服务可以维持原生协议的性能。因此,如果调用Java资源、原生Java类、EJB或者任何其他资源,不必补偿Web服务的性能开销。WSIF能够使用Java事务API(JTA),实现在被调用的支持事务的Java资源之间自动传送事务上下文。这样一来,Java资源就可以参与分布式事务。

为了了解WSIF的工作方式,要改动购买图书的BPEL流程,并调用Java类,然后调用EJB。别忘了,如果用WSIF,只要修改服务的WSDL,而不是修改BPEL代码。通过修改 WSDL,可以把调用绑定到Java资源上,而不是绑定到Web服务上。

首先,我们侧重于使用Java类,而不是图书等级Web服务。为了取代该Web服务,要有与该Web服务具有相同接口的Java类。 这需要基于Web服务描述语言(WSDL)契约来开发一个Java类。另一种可能就是让WSDL适应现有的Java类(或者另一资源,譬如EJB)。 第一种方法比较好,因为这是所谓的契约优先方法。 这样一来,服务的接口就可以满足BPEL流程的需要,而不是反过来。

Java到XML的绑定

要从BPEL中调用Java资源,需要使用BPEL变量中的数据,这些变量作为输入参数发送到Java资源,并从Java将数据返回给BPEL。BPEL变量是XML,而Java变量却不是XML,因此,需要在XML和Java之间进行映射。为了从Java中处理XML数据,有以下几个选择:

通过DOM(文档对象模型)API手动处理XML: 这样一来,相应Java方法的输入和输出参数,其类型将是万维网联盟(W3C)面向Java的DOM API中的Element。可使用DOM方法直接处理XML。

使用自动化的Java到XML的绑定: Java到XML的绑定能够自动把XML模式类型转换成Java类型。为此,需要生成一些接口和一组Java类。通过它们,就可以处理XML了。这样一来,XML被隐藏起来,但可以通过接口(如JavaBean)使用它。这里有两种选择: Oracle BPEL流程管理器: 通过使用XML外观(XML facades)支持默认的Java到XML的绑定; 使用定制的Java串行化程序。Oracle已经提供了定制的串行化程序,它们支持用于XML绑定的Java API(JAXB)、XML Bean 和 Axis Bean。当然,还可以编写自己的串行化程序。

XML外观

XML外观(XML facades)是Oracle BPEL流程管理器面向WSIF的原始Java到 XML的绑定,也是该产品的一个必要组成部分。XML外观是一组Java接口和类。通过它们,可以通过比较简单的方式,使用get/set方法来访问及修改BPEL变量中存储的XML数据。这种方式不要求直接处理XML。另外,XML隐藏在外观后面,这样就可以通过普通的Java接口来处理数据,这一概念被称为XML串行化。XML外观的想法是通过映射到内置类型,为基本的数据类型提供支持,并且利用XML模式生成复杂类型的Java类。表1显示了XML模式和Java类型之间基本数据类型的自动映射。

可以看到,大多数简单类型可以映射到基本类型或者对象类型。这很有用,因为可以让映射适应Java代码所用的实际类型。除了简单类型外,还需要映射复杂类型的一种方法,无论这类型是WSDL的 部分中定义的类型,还是外部XML模式(XSD)文件中定义的类型。譬如在图书等级Web服务WSDL中,将BookDscType类型的 BookRatingRequestMessage作为输入的一个操作。BookDscType这个复杂的XML类型用于 BookRatingRequestMessage和相应的BookRatingRequest BPEL变量:

< xs:schema elementFormDefault="qualified"

targetNamespace="/service/bookrating/">

< xs:complexType name="BookDscType">

< xs:sequence>

< xs:element name="Title" type="xs:string" />

< xs:element name="ISSN" type="xs:string" />

< xs:element name="Publisher" type="xs:string" />

< xs:element name="Authors" type="xs:string" />

< /xs:sequence>

< /xs:complexType>

< /xs:schema>

针对这个复杂XML类型的XML外观提供了一个接口和一个类,通过它们,可以使用Java getter方法来访问各元素(书名、国际标准期刊编号、出版社和作者)。XML外观还允许使用setter方法修改元素数据。该变量的XML外观包括一个接口(IBookDscType)以及提供下列这些方法的一个类(BookDscType): getTitle()和setTitle(); getISSN()和setISSN(); getPublisher()和setPublisher(); getAuthors()和setAuthors()。

还有一个工厂类(BookDscType

Factory),开发人员可以通过它使用createFacade()方法创建 IBookDscType。XML外观使代码更简单,也更容易维护,对含有许多成员字段的大型变量来说更是如此。

Oracle BPEL流程管理器提供了名为 schemac的模式编译器实用程序。使用该实用程序,可以生成XML外观。要为BookRating.wsdl生成XML外观,可使用下列命令行:

Z:\WSIF\2_JavaBindingClass>schemac BookRating.wsdl

-------------------------------------

Oracle XML Schema Processor Version 10.1.2.0.0

/bpel

Copyright (c) 2002-2004 - Oracle

(type schemac -help for help)

-------------------------------------

schemac> parsing schema file 'BookRating.wsdl' ...

schemac> Loaded schemas from wsdl located at BookRating.wsdl

schemac> generating XML business document ...

schemac> compiling XML business documents ...

Schemac completed successfully.

Z:\WSIF\2_JavaBindingClass>

要从Java资源中使用这些类,就需要把它们编译到C:\OraBPELPM_1\

integration\orabpel\system\classes目录,BPEL服务器就能访问它们。schemac实用程序有几个选项。可以使用-d参数选项定义存储生成的外观所在目录。想查看外观源代码,需要使用-trace选项。schemac实用程序还可以用于使用Java类生成XML的模式。如果希望让服务接口适应现有的Java资源,这很有用。

开发Java类

要用Java类取代图书等级Web服务、又不用修改BPEL,就需要与原始图书等级Web服务具有相同接口(契约)的Java类。这意味着Java类必须提供具有相同功能的操作,而且这些操作必须接受相同的参数、返回相同的结果类型,但操作名不必相同。看看原始WSDL就会发现图书等级Web服务提供了名为BookRating的操作,该操作接受输入和输出消息,因而是同步的:

< portType name="BookRatingPT">

< operation name="BookRating">

< input message="tns:BookRatingRequestMessage" />

< output message="tns:BookRatingResponseMessage" />

< /operation>

< /portType>

这两个消息的签名如下:

< message name="BookRatingRequestMessage">

< part name="book" type="tns:BookDscType" />

< /message>

< message name="BookRatingResponseMessage">

< part name="rating" type="xs:int" />

< /message>

该操作的输入参数类型是BookDscType。要把BookDscType映射到Java,就要使用相应的XML外观,也就是之前使用schemac工具生成的XML外观。该操作的返回类型是BookRatingResponseMessage消息,其类型是xs:int。xs:int类型映射到java.lang.Integer。它还可以映射到int或者java.math.BigInteger,但在这里使用的是java.lang.Integer。

现在该为图书等级Web服务编写Java等价类了。调用新的Java类 BookRatingJava,该类含有一个名为getBookRating的方法。该方法的主体部分非常简单: 把通知打印到服务器控制台,然后返回等级4(在实际例子中,可以根据数据库中的数据来计算图书等级)。代码如下所示(注意如何使用getTitle()方法和getISSN()方法来分别访问书名和国际标准期刊编号):

package com.oracle.rating;

import com.oracle.service.bookrating.*;

public class BookRatingJava {

public Integer getBookRating (BookDscType book) {

System.out.println("Book rating for "+book.getTitle()+" ("+book.getISSN()+"): 4.");

return new Integer(4);

}}

此处添加控制台输出,是为了确认流程确实调用了Java类,而不是Web服务。

用WSDL定义WSIF绑定

要“说服”BPEL流程使用Java类、而不是Web服务,必须定义到Java类的WSIF绑定。这一步在图书等级WSDL(可以在此添加绑定部分)中执行。

每个WSIF绑定由两部分组成。首先,必须定义实际绑定,可以在其中指定: 所用的绑定类型(Java类、EJB和JCA等)。类型映射,可以在其中指定XML类型到目标类型(对Java资源而言,这些是Java类型)的映射,必须为所有复杂类型定义映射,简单类型可根据前面那张表自动进行映射。操作映射,必须在其中为每个WSDL操作(在标记处定义)指定目标资源中的相应操作(譬如,Java类的方法名)。

其次,必须指定将使用的服务,此处要指定资源的确切名称。如果它是Java类,要指定其全名(包括程序包名称)。

在实际情况下,某个资源(如Java类或者EJB)可能没有相应的WSDL。那么就要完成下列步骤:

1.定义Java到XML的绑定,在其中选择如何映射输入参数、将值返回给XML。可以使用XML外观,并使用schemac工具、结合-R参数选项来简化这项工作,该选项会根据Java类生成XML模式。

2.定义每个操作的签名以及相应的输入和输出消息。

3.添加WSIF绑定。

4.添加< partnerLinkType>声明,以便从BPEL流程中使用WSDL。

尤其是在前两个步骤中,可以使用工具或者向导程序,让资源自动转换成Web服务。 大多数环境都有这类工具。当然,实际上并没有把资源转换成Web服务,但可以利用生成的WSDL(需要另外修改)。

针对Java类的WSIF绑定

现在不妨为图书等级Java类定义WSIF绑定。首先在WSDL文档的根元素( 标记)中定义WSIF提供程序使用的两个命名空间。格式命名空间用于定义类型映射,而Java命名空间用于定义操作映射以及 Java类的全名:

< ?xml version="1.0" encoding="utf-8" ?>

< definitions xmlns:xs="/2001/XMLSchema"

xmlns:tns="/service/bookrating/"

targetNamespace="/service/bookrating/"

xmlns="/wsdl/"

xmlns:plnk="/ws/2003/05/partner-link/"

xmlns:format="/wsdl/formatbinding/"

xmlns:java="/wsdl/java/" >

接下来,添加绑定部分。该部分通常位于端口类型声明之后、合作伙伴链接类型之前。 下面为BookRatingPT端口类型定义Java绑定:

1.定义从XML到Java的类型映射。输入参数XML类型: BookDscType映射到 com.oracle.service.bookrating.BookDscType Java类。请注意,不必为输出XML xs:int 类型提供映射,因为它自动映射到java.lang.Integer。

2.还要定义WSDL操作BookRating映射到Java方法getBookRating()。 请注意: WSDL 操作的名称和Java类的方法名不必相同,但输入参数和返回参数的类型要相同:

< binding name="JavaBinding" type="tns:BookRatingPT">

< java:binding/>

< format:typeMapping encoding="Java" style="Java">

< format:typeMap typeName="tns:BookDscType"

formatType="com.oracle.service.bookrating.BookDscType" />

< /format:typeMapping>

< operation name="BookRating">

< java:operation methodName="getBookRating"/>

< input/>

< output/>

< /operation>

< /binding>

然后,指定使用的服务。定义该服务由Java类提供。图书等级服务将使用com.oracle.rating.BookRatingJava Java类:

< service name="BookRating">

< port name="JavaPort" binding="tns:JavaBinding">

< java:address className="com.oracle.rating.BookRatingJava"/>

< /port>

< /service>

图书等级WSDL的其余部分(包括合作伙伴链接类型)没有变动。 (沈建苗编译)

链接:背景资料

WSIF是Apache的Web服务项目的一个子项目,目前版本是2.0,实际上是WSIF被提交给ASF后的第一次版本,命名为2.0是和以前非Apache的1.x版本相区别。WSIF提供了一组简单的API来调用Web服务而不需要了解该Web服务的实现方式,更深入地说,WSIF是一组基于WSDL文件的API,它调用可以用WSDL文件描述的任何服务。

WSIF中提供的API允许编程者通过WSDL描述内容和Web服务调用的抽象层打交道,而不是直接使用SOAP来调用Web服务。编程者使用WSIF后就可以使用统一的编程模型来调用Web服务而不需要了解该Web服务是如何实现和被访问的。

WSIF 2.0中里面提供了下列内容的支持:SOAP(可以使用Apache SOAP或者axis实现)、本地Java类、EJB、JMS services和其他可以通过Java connector访问的应用。WSIF规定了特别的WSDL扩展使这些资源可以被当成WSDL描述的服务访问。WSIF允许通过运行时分析Web服务描述的元数据来实现无stub或者动态的调用一个Web服务。允许在运行时将更新的绑定实现插入到WSIF中,允许调用的服务在运行时之前选择自己的绑定实现。

上一篇:软件产品化是必由之路 下一篇:富于表情的虚拟人脸合成