精彩的人生

好好工作,好好生活

BlogJava 首页 新随笔 联系 聚合 管理
  147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks

Applying the Web services invocation framework

Calling services independent of protocols

独立于协议的服务调用

Paul Fremantle (pzf@uk.ibm.com)
Senior Software Engineer, IBM Application and Integration Middleware
01 Jun 2002

Web 服务调用框架,提供了一种与传输协议和服务所在地无关的 web 服务调用方式。某种程度上可以把 WSIF 叫做不基于 SOAP 的简单应用开发。了解 Apache Software Group 发布 WSIF 的最新变化。

 

Introduction

Web 服务调用框架( WFIS )是一种用来调用 Web 服务的简单的 Java API ,而且不论服务在何时何地被提供。它把开发者,从必须为一些特定的传输协议和服务环境提供服务的束缚中解放出来。因此,它提供一个 API 提供独立绑定,来访问各种 Web 服务。它允许无存根或完全动态地调用 Web 服务,这是基于一种在运行时检查服务元数据的技术。它也允许允许在运行时插入一个升级的任务绑定。如果你使用的 WSIF 提供者允许,也可以实时插入一个新的绑定。它也能选择一个绑定延来期调用服务,直到运行时再绑定。最后,它是基于 WSDL 的,所以他可以调用任何 WSDL 中描述的服务。

WSIF 最初发布在 2001 10 月份的 alphaWorks AlphaWorks 自从被发布以来被下载了 4000 多次。 WSIF 的创立者之一写了两篇很优秀的文章,来描述其建立 WSIF 的动机和它的使用,推荐大家读一下 (See Web service invocation sans SOAP, Part 1 and 2 )

这篇文章符合 Apache 软件基金会对 WSIF 捐赠要求。 WSIF 源码是由 Apache XML 项目捐赠,并且在 Axis work 赞助下完成。可以在 Apache CVS 目录下获得,目录名是 xml-axis-wsif 。代码在 http://cvs.apache.org/viewcvs.cgi/xml-axis-wsif

在这篇文章中,我将关注 WSIF Motivation ,使用和构架。自从 alphaWorks 发布后 WSIF 的变化就被总结概括,这篇文章也包含一些实验性的和未来的观点。但是在此之前,我将快速的回故一下 WSDL

 

Some background on WSDL

Web 服务描述语言( WSDL )从一开始就具有可扩展性。在 WSIF 中,设计者把接口和服务执行分离。

 

WSDL 中一个服务被清楚地定义为三个部分:

1. The PortType 它定义了服务提供的抽象接口。一个 PortType 定义了一系列操作。每个操作能被 In-Out (请求-响应), In-only Out-only, Out-in (征求-响应)。每个操作都定义了输入或输出消息。一个消息被定义为一系列部分( part ),每个部分包含一个 Schema 定义类型。

2. The Binding 一个绑定定义了抽象 PortType 与一个服务的数据格式和协议是如何映射的。例如, SOAP 绑定定义了编码方式, SOAP Action header body 的名字空间(目标 URI )等等。

3. The port 它定义了服务所在的实际位置( endpoint ),比如,在 SOAP 服务器上可获得的 HTTP URL

 

现在的 WSDL ,每个 port 有且只有一个绑定,每个绑定只有一个 PortType 。相反(更重要的是),每一个服务( PortType )能包含多个端口,每个端口代表一种可以供选择的位置和绑定用以访问那个服务。

当我们设计 WSIF 时我们先把它做为 WSDL 的镜像,因为我们需要基于 WSDL API 而不是直接基于 SOAP WSIF 是一个框架有效地支持传输和格式化。 WSIF 中的 provider 支持 SOAP

 

WSDL 加上了可扩展元素后,和 SOAP 相比,它能够建立其它的服务。典型地, web 服务是用已有的应用组建构造,比如 JAVA 类,企业级 JAVA BEAN ,或 COM 对象。这些组件有时被封装成应用程序运行在特定的系统,比如大型机事务处理系统。通过扩展 WSDL 来描述已有的组件模型,我们能获取被暴露的 SOAP available 服务和下面的组件之间的继承关系, ….. 。事实上,为已存在的组件加上可扩展元素有更多的用途——它为已有的组件模型加上了面向服务构架的描述能力。

 

Motivation for WSIF

提出 WSIF 的动机是我们希望看到“面向构架的服务”应用更加广泛,而不是仅仅的 SOAP 。现在,有大量不同的协议,传输和分布式计算技术能够提供比 SOAP 更多的东西,尤其是在管理,交易安全,和服务质量( QoS )方面。而 SOAP 之所以能够后来居上,主要是原因是资金投入。许多公司已经投入了大量资金在的技术上,比如 CORBA ,他们当然希望能够继续使用这些技术。另一方面,使用 SOAP Web 服务有一个独特的优势——描述和发现的构架。任何人都可以从 UDDI 目录或一个 inspection 文档中下载 WSDL 文档,并且使用一个普通的工具生成的代码就可以使用服务,不论服务是在局域网还是通过 Internet 。脚本语言的使用也使其它工具得到发展——比如一些组成和设计服务的语言( XLANG WSFL )。

We really wanted to make the extensibility and structure of WSDL real. WSDL allows us to describe existing systems using extensibility elements. For example, we have written WSDL extensions to describe transactions in CICS and IMS using connectors, calls to remote stateless session Enterprise JavaBeans, as well as SOAP and non-SOAP messages over JMS-based messaging systems. However, while describing things is useful, it isn't as useful as executing them.

 

现在, WSDL 不仅仅是一个描述层——它已经用于一些工具中,这些工具使用 WSDL 描述来生成访问服务的存根。所以,如果我们为非 SOAP 系统加上描述,我们将失去那些好处。 WSIF 是一个可插入的框架,它允许 provider 插入。一个 provider 就是一段代码,它支持 WSDL 扩展,并且通过特定的执行可以调用服务。这就意味着客户端的代码是和(服务器端)执行无关的,它仅仅依赖服务的 PortType WSIF 同时也支持延迟绑定,即一个新的 Provider 和描述可在运行时获得,而已有的客户端可使用这个新的 implementation 。最后, WSIF 允许客户端为 infrastructure runtime 代理端口的选择,这使用户在服务质量特性和商务策略的基础上选择 implementation

 

WSDL 的结构允许一个 Web 服务有多个 implementation ,多个端口共享一个 PortType 。换句话说, WSDL 允许同样的端口绑定到 SOAP IIOP 。我们希望我们的 API 允许同样的客户端代码访问任何可以获得的绑定——如果代码为 PortType 而写,那么它在端口和绑定被使用时应该能被部署或配置(或代码选择)。

 

我们为 WSIF 提出了一下要求,它必须:

1. Support any valid WSDL extensions. 支持任何合法的 WSDL 扩展。

2. Support dynamic invocation of WSDL-described services. 支持 WSDL —描述服务的动态调用。

3. Support an API based on WSDL PortTypes. 支持基于 WSDL 端口类型的 API

4. Allow late binding to different formats and transports. 允许延迟绑定不同的数据格式和传输。

5. Support both compiled and dynamic approaches. 支持编译和动态 approaches

6. Support minimum code deployment scenarios (n providers, no per-service code). 支持最小代码部署方案( n provider no persevice 代码)。

7. Support different in-memory representations of service request data.

 

WSIF usage

WSIF 的用法有两种:基于存根的模型和动态调用接口( DII )。

Stub model
基于存根的模型允许使用者使用泛型编程模型,调用服务器上的业务函数。从 WSDL接口到JAVA定义接口的映射已经被规范花——在JAXRPC标准中。有些人试图通过JCP/JSR过程把WSIF模型有JAXRPC整合起来,但是从这个角度上看WSIF总是显得太试验化了。我们所能做的只能是松散的整合。JAX-RPC定义了服务定义接口(SDI)——存根的业务接口。WSIF也定义了一个接口想JAXRPC一样来使用同样的SDI。所以,尽管WSIFJAXRPC不能共享接口,他们却共享工具(比如,Axis WSDL2Java)。Listing 1是一个存根模型的例子。

WSIFService sq  =  ServiceFactory.newInstance().getService( " http://my.com/svcs/stockquote.wsdl " ); 
MyService mySvcStub 
=  sq.getStub( " soap " , MyService. class ); 
mySvcStub.myMethod(); 


Dynamic invocation interface
DII
WSDL十分相近。在WSDL中,每个操作都有一个输入消息和可选的输出或错误消息。在WSIF中,我们划分了相似的层次。基本上是对应的。事实上,我们的第一次迭代是一一对应的,但是我们归纳的更有逻辑性更(简便)简单。对应关系如Table 1: Correspondence of WSDL and WSIF entities所示。

Table 1: Correspondence of WSDL and WSIF entities

WSDL

WSIF

(WSIL/UDDI)

WSIFServiceFactory or JNDI

Service

WSIFService

Port

WSIFPort

Binding

( 无对应项)

Operation

WSIFOperation

Message

WSIFMessage

Part

( 无对应项)

使用DII你需要:

  1. Select a port. 选择一个端口

  2. Create an operation. 建立一个操作

  3. Create and populate the in-message. 建立并组装输入消息。

  4. Execute the operation. 执行操作

  5. Read the response data from the out-message. 从输出消息中读取响应数据。

一个简单的例子如 Listing 2所示。

WSIFService sq  =  ServiceFactory.newInstance().getService( " http://my.com/svcs/stockquote.wsdl " ); 

WSIFPort defPort 
=  sq.getPort(); 

WSIFOperation getQ 
=  defPort.createOperation( " getQuote " ); 

WSIFMessage inMessage 
=  getQ.createInputMessage(); 

inMessage.setStringPart(
" symbol " " IBM " ); 

 

getQ.executeRequestResponse(inMessage, outMsg, fltMsg); 

outMessage.getFloatPart(
" value " ); 


AlphaWorks发布的WSIF的特性之一是有一个命令行参数工具——Dynamic Invoker,这个工具能调用任何接口具有简单类型的Web服务。我们通常请求的服务是,参数使用了复杂类型的动态调用服务。WSIF就是基于这个思想设计的,但是对于第一次迭代我们仅仅支持使用JavaBean组件的服务,所以如果没有先产生一个合适的JavaBean组件,你将不能调用服务。作为补救,我们开发了一系列的名为JROM的类(起初它是支持Java记录对象模型(JROM),由JayRom声明,但是现在它仅仅是个名字而已)。JROM是一个抽象的树状结构,这种结构能代表内存中很多schema复杂类型。JROM作为轻量级的DOM,它的树装结构的每个叶子节点都是一个基本类型(不像DOM都是字符串)。

通过和WSIF一起使用JROM,动态调用甚至容许在Classpath中没有与Schema复杂类型相匹配的Java类型。这是一种十分有力的方式,尤其是在建立一个动态web服务系统时,如网关,流引擎,测试客户端。不是所有的Provider都支持JROM,但是我们在ApacheSOAP Provider中加入了对JROM的支持。

JROM 不是WSIF开源项目发布的一部分,但是它可以从alphaWorks中获得,见 www.alphaworks.ibm.com/tech/jrom.

WSIF architecture
WSIF
的架构是基于一些工厂类的。使用工厂类的原因是,这样可以隐藏对象是所使用的是“静态”还是“动态”。在静态的情况下,对象被创建以提供特定的端口,消息或操作。静态时implementation可以快速建立。在动态情况下,对象使用WSDL描述在运行时控制特定的端口,操作或消息传递。目前WSIF主要用于动态对象,就像我们最初怎样设计它们的一样。我们把WSIF分为不同的动态度。

Fully dynamic architecture 完全动态架构

在流控制引擎中可能用到,流的描述作为一个XML文档被提供。流引擎在发送消息给其他的操作之前处理消息,以聚合成一个新的服务。被部署的代码是每个绑定类型一个Provider。因此,这是一个b结构,b是一些不同的WSDL绑定扩展。

Semi-dynamic architecture 半绑定构架
定义了PortType的消息被静态编译,但是绑定本身是动态的。这就要求代码部署基于PortType,且每个绑定一个Provider。因此,这是一个pb结构,其中p是一些PorTypeb是一些WSDL绑定。当接口变化时,编译的消息必须被部署。

Static architecture 静态构架
WSDL 绑定和端口都是静态编译。在这种情况下,在tooling time被定义的默认端口被编译。代码部署是每个绑定实例一个实体,因此,可看作是p×b 结构。

Changes since the alphaWorks release alphaworks发布后的变化
There are a number of changes since the alphaWorks release. You are encouraged to look at the open source code tree yourself. The main changes are:

  • Simplification of the WSIFMessage and WSIFPart model. We removed the WSIFPart interface and merged it into WSIFMessage. In order to capture different styles of using WSIFMessage, we added a method getRepresentationStyle().

  • Renaming of the PortFactory object to Service.

  • Addition of a ServiceFactory interface.

  • Change from using the PortTypeCompiler to using the J2SE 1.3 dynamic proxy support.

  • Addition of new bindings and transports -- SOAP over JMS, EJB binding, Apache Axis-based SOAP provider.

  • Support for tracing and logging activity.

  • Support for dynamic registration of new providers using the J2SE JAR service provider spec (see Resources).

Experimental additions to WSIF
目前WSIF有许多研究领域,异步请求-响应消息和contextaware消息是其中的两个。

Asynchronous request-response
现在有一个异步请求-响应模型,响应(response)在由请求引发的不同运行线程中被处理。为了支持它,请求者注册一个返回对象或句柄,它们在响应到达时被调用。

当请求消息被发送之后,句柄对象被传递给WSIFOperationWSIF提供一个相关的服务来存储句柄而不是提供一个identifierWSIFOperation调用WSIF相关的服务,这个服务存储了服务本身和请求句柄使用的相应的ID。这都发生当前事务的内部。如果用户请求指定了一个事务队列,那么这些工作在当前事务内完成。

WSIFOperation WSIFResponseHandle对象是序列化的,所以句柄对象的状态能被保持,即使万一在响应和请求时系统出错也可以被保持。相应的服务也是可插入的,而其他的特性,比如原子事务和持续性都能保证高可靠性。

当某个延迟端口响应到来时,监听线程将捕获它并传递给用作存储的WSIFOperation。操作包括把响应散列成WSIFMessage逻辑,并执行句柄函数executeAsyncResponse(),此函数以outMessage为参数。监听线程运行在不同事务上,这些事务源自原始的请求。响应也因此把事务和请求分割开来。

例如, Listing 3显示了一个句柄如何通过实现(implement)接口类WSIFResponseHandler而来。此Handler是用来解释响应消息和使用响应值的。

Listing 3. Implementing an asynchronous handler in WSIF

public   class  QuoteHandler  implements  WSIFResponseHandler   {          

protected  String symbol  =   null //  local storage of the symbol we wanted quoted
public   void  setSymbol(String value)  { symbol  =  value } ;    

public   void  executeAsyncResponse(WSIFMessage out, WSIFMessage fault)  {
//  this simplified example assumes no failures and that the symbol has been set correctly 

float  quoteValue  =  out.getPart ( " quote " );
updateQuoteDB(symbol, quoteValue);
}
 


服务调用如 Listing 4示:

Listing 4. Invoking a service asynchronously with WSIF

String symbol  =   " IBM "

QuoteHandler quoteHandler 
=   new  QuoteHandler(); 

quoteHandler.setSymbol(symbol); 
//  the handler needs to knowthe symbol when it gets executed later.   

WSIFMessage inMessage; 

WSIFOperation quoteOperation; 

 

inMessage.setXXXPart(
//  set up inMessage for invocation 

quoteOperation.executeAsyncRequestResponse(inMessage, quoteHandler); 


Content-aware message内容-提醒消息
我们也希望支持设定和使用上下文。W3Cweb服务工作小组也就这个主题讨论过,但是没有规定语法和语义。

例如,一个SOAP/HTTP端口可能要求得到HTTP用户名和密码。这些信息对于服务调用来说十分特殊,但是通常又并非是服务参数的一部分。在总体上,上下文被定义成一系列name-value对。但是,Web服务需要使用XML schema类型定义数据类型,用“namevalue对”表示上下文的方法可用表示 WSIFMessage 的方法来替代——即一组被命名的Part,每个part等价于一个XML Schema类型实例。这虽然稍稍超出了使用属性的概念,但是更多的保持了WSDLWSIF的特点。

The methods setContext() and getContext() on a WSIFPort and WSIFOperation allow the application programmer or stub to pass context information to the binding. The Port implementation may use this context -- for example to update a SOAP header. There is no definition of how a Port may utilize the context.

WSIFPort WSIFOperation 上的 setContext() getContext() 函数允许应用程序员或者存根通过上下文信息绑定。 Port 的实现也会用到这些上下文——比如升级一个 SOAP 头。但 Port 怎样使用上下文没有定义。

Ideas for the future
There are a number of areas in WSIF we would like to see work on to improve its functionality and usefulness. First, we would like to have refactoring capabilities to separate the transport from message formatting. We have defined a WSIFFormatter class to allow access to and conversion of the data into a native format.

Next, an abstract tree representation of the data in a a message would be useful. Currently, we mainly use compiled classes from the schema to carry the service parameters in WSIFMessage. However, in one implementation of WSIF, the Web Services Gateway (see Resources), we use an abstract tree notation called JROM that closely maps to an XML Schema.

We would also like to see more and better providers for the many types of transports and object systems that exist. Finally, an implementation of WSIF in C or C++ would certainly be helpful to developers creating services in those languages.

Summary 小结
WSIF 是一个开源的面向服务的框架,它允许SOAP和非SOAP服务在WSDL中定义并用普通的方式调用。WSIF定义了可插入的接口(Provider接口)来支持新的传输和协议。通过支持代理接口和动态调用接口,WSIF能够使最终用户和系统软件开发者这使用多种些协议支持WSIF提供的接口。WSIF支持延迟绑定,这样服务可以被重新绑定到一个新的协议上而不需要改变代码。The open source WSIF codebase includes providers for Java, EJB, and SOAP (over HTTP and JMS). WSIF has been used in WebSphere Enterprise Edition 4.1 and Versata's Logic Server WebServices Add-On.

Acknowledgments
The main contributors to the WSIF release, in alphabetical order, are: Aleksander A. Slominski, Anthony Elder, Dieter Koenig, Gerhard Pfau, Jeremy Hughes, Mark Whitlock, Matthew J. Duftler, Michael Beisiegel, Nirmal Mukhi, Owen Burroughs, Paul Fremantle, Piotr Przybylski, and Sanjiva Weerawarana

Resources

About the author
Paul Fremantle is an architect in IBM's Hursley Laboratory, working on Web services components in IBM WebSphere Application Server, as well as open source projects such as WSDL4J and WSIF. Paul is the co-lead of the Java standard JSR110: Java APIs for WSDL. Paul previously worked as a WebSphere specialist in the software group and as an architect in IBM Global Services. Before joining IBM, Paul worked as a consultant in the pharmaceutical industry.
His publications include articles on porting EJBs from WebLogic to WebSphere, and a Redbook, "The XML Files: Using XML and XSL in WebSphere." Paul has presented at ApacheCon, XML Europe, Software Architecture, and other industry conferences. He has an M.A. in Mathematics and Philosophy and an M.Sc in Computation from OxfordUniversity.
You can contact Paul at pzf@uk.ibm.com.

转载自:http://it.jiulove.com/inc/news/20050731/11292026111.asp

posted on 2006-05-15 17:31 hopeshared 阅读(921) 评论(0)  编辑  收藏 所属分类: Web Service

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


网站导航: