Web Services体系结构是面向对象分析与设计(OOAD)的一种合理发展(logical evolution),同时也是电子商务解决方案中,面向体系结构、设计、实现与部署而采用的组件化的合理发展(logical evolution of components geared towards the architecture, design, implementation, and deployment of e-business solutions)。这两种方式在复杂的大型系统中经受住了考验。和面向对象系统一样,封装、消息传递、动态绑定、服务描述和查询也是Web Services中的基本概念,而且,Web Services另外一个基本概念就是:所有东西都是服务,这些服务发布一个API供网络中的其他服务使用,并且封装了实现细节。
因此可以这么说:
Web Services是自包含的、模块化的应用程序,它可以在网络(通常为Web)中被描述、发布、查找以及调用。
Web Services是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。
Web Services是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。
SOA体系结构中的组件必须具有上述一种或多种角色。在这些角色之间使用了三种操作:
① publish操作:使Service provider可以向Service broker注册自己的功能及访问接口
② find操作:使Service requester可以通过Service broker查找特定种类的服务
③ bind操作:使Service requester能够真正使用Service provider
SOAP即简单对象访问协议(Simple Object Access Protocol)
说到Web Services你就很难把它与SOAP分开,SOAP是用于交换XML编码信息的轻量级协议。它有三个主要方面:
XML-envelope为描述信息内容和如何处理内容定义了框架;
将程序对象编码成为XML对象的规则;
执行远程过程调用(RPC)的约定。
SOAP 可以运行在任何其它传输协议上。例如, SMTP,在传输层之间的头是不同的,但XML有效负载保持相同。表面看来,基于 XML 的模式本应比基于二进制的慢,但它并不像表面那么简单。首先,当SOAP被用于通过因特网发送消息时,在每个端点给消息编码/解码的时间与在端点间传输字节的时间相比较是微不足道的,所以这种情况下使用 XML 没太大问题。
WSDL(Web Service Definition Language)
WSDL 是一种XML Application,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务访问点对包含面向文档信息或面向过程调用的服务进行访问(类似远程过程调用)。WSDL首先对访问的操作和访问时使用的请求/响应消息进行抽象描述,然后将其绑定到具体的传输协议和消息格式上以最终定义具体部署的服务访问点。相关的具体部署的服务访问点通过组合就成为抽象的Web服务。
在具体使用中,我们可以对 WSDL 进行扩展(类似SOAP的可扩展性),这样无论通信时使用何种消息格式或网络协议,都可以对服务访问点及其使用的消息格式进行描述。在WSDL的框架中,可以使用任意的消息格式和网络协议,如同SOAP中可以使用任意的网络协议一样。在WSDL规范中,定义了如何使用SOAP消息格式、HTTP GET/POST消息格式以及MIME格式来完成Web服务交互的规范。
WSDL 文档在Web服务的定义中使用下列元素:
Types - 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。
Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构。
Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。
PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持。
Binding - 特定端口类型的具体协议和数据格式规范的绑定。
Port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。
Service- 相关服务访问点的集合。
Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构。
Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。
PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持。
Binding - 特定端口类型的具体协议和数据格式规范的绑定。
Port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。
Service- 相关服务访问点的集合。
WSDL元素的对象结构示意图:
其中,Types是一个数据类型定义的容器,包含了所有在消息定义中需要的XML元素的类型定义,我将在今后的文章中结合XML Schema来详细说明如何进行类型定义。
Message具体定义了在通信中使用的消息的数据结构,Message元素包含了一组Part元素,每个Part元素都是最终消息的一个组成部分,每个Part都会引用一个DataType来表示它的结构。Part元素不支持嵌套(可以使用DataType来完成这方面的需要),都是并列出现。
PortType具体定义了一种服务访问入口的类型,何谓访问入口的类型呢?就是传入/传出消息的模式及其格式。一个PortType可以包含若干个Operation,而一个Operation则是指访问入口支持的一种类型的调用。
在WSDL里面支持四种访问入口调用的模式:
单请求;
单响应;
请求/响应;
响应/请求。
单响应;
请求/响应;
响应/请求。
在这里请求指的是从客户端到Web服务端,而响应指的是从Web服务端到客户端。PortType的定义中会引用消息定义部分的一个到两个消息,作为请求或响应消息的格式。比如,一个股票查询的访问入口可能就会支持两种请求消息,一种请求消息中指明股票代码,而另一种请求消息中则会指明股票的名称,响应消息可能都是股票的价格等等。
以上三种结构描述了调用Web服务的抽象定义,这三部分与具体Web服务部署细节无关,是可复用的描述(每个层次都可以复用)。如果与一般的对象语言做比较的话,这部分可以堪称是IDL描述的对象,描述了对象的接口标准,但是到底对象是用哪种语言实现,遵从哪种平台的细节规范,被部署在哪台机器上则是后面的元素所描述的。
Service描述的是一个具体的被部署的Web服务所提供的所有访问入口的部署细节,一个Service往往会包含多个服务访问入口,而每个访问入口都会使用一个Port元素来描述。
Port描述的是一个服务访问入口的部署细节,包括通过哪个Web地址(URL)来访问,应当使用怎样的消息调用模式来访问等。其中消息调用模式则是使用Binding结构来表示。
Binding结构定义了某个PortType与某一种具体的网络传输协议或消息传输协议相绑定,从这一层次开始,描述的内容就与具体服务的部署相关了。比如可以将PortType与SOAP/HTTP绑定,也可以将PortType与MIME/SMTP相绑定等。
在介绍了WSDL的主要元素之后,大家会发现,WSDL的设计理念完全继承了以XML为基础的当代Web技术标准的一贯设计理念:开放。WSDL允许通过扩展使用其他的类型定义语言(不光是XML Schema),允许使用多种网络传输协议和消息格式(不光是在规范中定义的这些:SOAP/HTTP,HTTP-GET/POST以及MIME等)。同时WSDL也应用了当代软件工程中的复用理念,分离了抽象定义层和具体部署层,使得抽象定义层的复用性大大增加。
WebService之Axis2
在众多的WebService实现中,axis2( http://ws.apache.org/axis2/)应该算是一个很不错的支持环境了。Apache对它的描述是“a redesign of Axis (1.X) supporting SOAP 1.2/SOAP1.2/REST/and more”——是对Axis (1.X)的重新设计同时支持SOAP 1.2/SOAP1.2/REST等协议。从最初的 Apache Axis 和 Apache SOAP 到目前的 Axis2,经历了很大的发展。它不仅更高效、模块化、基于 XML,而且具有灵活性和可扩展性,实现了安全性和可靠性等企业功能。Apache Axis2 的易用性和功能确实使其成为了下一代 Web 服务平台。
Axis2 体系结构将逻辑与状态分离;这允许在并行线程中执行逻辑。服务和调用的静态状态和动态状态分别存储在 Description 和 Context 类中。Axis2 体系结构是使用 7 个独立模块实现的。
信息模型:此模块管理 SOAP 引擎的状态。该模型定义一组用于存放状态的类,而引擎管理这些信息对象的生命周期。信息模型包含两种用于存放状态的类。Description 类存放本质上是静态的且存在于 Axis 引擎实例的整个生命周期中的数据(如传输、服务和操作的配置)。Context 类存放调用上下文中有效的服务和操作的动态信息,例如当前请求和响应 SOAP 消息、From 地址、To 地址和其他元素。
XML 处理模型:Axis2 引入了一个名为 AXIOM 的新模型,用于处理 SOAP 消息。AXIOM 使用 StAX (Streaming API for XML) 来解析 XML。StAX 是一个标准的流式 Pull 解析器 Java™ API。AXIOM 非常精巧,不会减慢 XML 信息集的构建速度——换句话说,对象只有在绝对必要时才会创建。总体而言,AXIOM 和 Axis2 所占用的内存要小于 Axis 1 所占用的内存。Axis2 对象模型(AXIs2 Object Model,AXIOM)是 Axis2 的基础,任何 SOAP 消息在 Axis2 中都表示为 AXIOM。AXIOM 相对于其他 XML 表示形式的优势在于,它基于
pull 解析器技术,而其他大多数则基于
push 解析器技术。pull 与 push 的主要不同之处在于,在 pull 技术中,调用者对解析器具有完全控制权,可以要求下一个事件;而对于 push,当要求解析器继续处理时,它将触发事件,直到达到文档最后为止。由于 AXIOM 基于 pull 解析器技术,因此具有“随需应变构建”功能,仅在被要求时才会构建对象模型,而且,如果需要,可以直接从 AXIOM 访问基础 PULL 解析器并对其加以使用,而不用构建对象模型(Object Model,OM)。
SOAP 处理模型:Axis2 体系结构定义了两个管道(或流),分别称为 InPipe (InFlow) 和 OutPipe (OutFlow),用于处理服务器端的请求消息和响应消息。在客户端,这两个管道是反向的——换句话说,SOAP 请求消息流经 OutPipe,而响应消息流经 InPipe。管道或流包含一系列分为阶段的处理程序。阶段按照预先定义的顺序执行,如上面的图 1 所示。除预先定义的阶段和处理程序集外,用户还可以在操作级别、服务级别或全局级别配置用户阶段和相关处理程序。处理程序充当 SOAP 消息的拦截器,可以处理 SOAP 消息的 Header 或 Body。InPipe 是通过以下阶段进行配置的:
TransportIn
PreDispatch
Dispatch
PostDispatch
PolicyDetermination
User phases
Message validation
PreDispatch
Dispatch
PostDispatch
PolicyDetermination
User phases
Message validation
请求消息在通过 Inpipe 中配置的所有阶段后,到达 MessageReceiver,然后由MessageReceiver调用实际服务实现。
服务器的 OutPipe 包含以下阶段:
Message initialization
Policy determination
User phases
MessageOut
Policy determination
User phases
MessageOut
用户配置的阶段位于这两个管道的用户阶段(User phases) 部分。如果在执行这些管道的过程中发生错误,则这些错误将通过 InFaultPipe 或 OutFaultPipe 管道。收到 Fault 消息后,在客户端调用 InFaultPipe;如果某个调用导致将错误发送到客户端,则在服务器端调用 OutFaultPipe。用户可以将处理程序添加到预先定义的阶段,并且按照这些处理程序运行的顺序进行配置。
部署模块:此模块配置 Axis 引擎并部署服务和模块。axis2.xml(在 webapps/axis2/WEB-INF 中)包含 Axis2 引擎的全局配置,包括:
全局模块 (Global modules)
全局接收器 (Global receivers)
传输 (Transports)
用户阶段定义 (User phase definitions)
全局接收器 (Global receivers)
传输 (Transports)
用户阶段定义 (User phase definitions)
每个服务的配置都包含在服务存档的 services.xml 文件中。本文稍后将详细讨论此文件。
WSDL 和代码生成:此模块从 WSDL 文件中生成客户端存根和服务器框架代码。Axis2 代码生成器发出采用正确 XML 样式表的 XML 文件,以用所需语言生成代码。
客户端 API:Axis2 客户端 API 调用遵循 WSDL 2.0 定义的 In-Only 和 In-Out 消息模式的操作。客户端 API 支持 In-Out 操作的阻塞和非阻塞调用。
传输:此模块包含与传输层交互的处理程序。传输处理程序有两种类型:TransportListener 和 TransportSender。TransportListener 从传输层接收 SOAP 消息,然后将其传送到 InPipe 进行处理。TransportSender 发送通过指定传输从 OutPipe 接收到的 SOAP 消息。Axis2 提供 HTTP、SMTP 和 TCP 的处理程序。对于 HTTP 传输,服务器端上的 AxisServlet 和客户端上的一个简单的独立 HTTP 服务器(由 Axis2 提供)充当 TransportReceiver。
Axis2特性:
经改进的部署模型
Axis2 现在支持将服务热部署到 Axis2 引擎中。这就允许用户在不用重新启动服务器的情况下部署服务。服务应该存档为 ZIP 文件,且在文件名中使用 .aar(Axis2 存档,Axis2 archive)作为扩展名。服务存档包含以下信息:
服务实现类
Services.xml 文件描述其使用的消息接收者、所需的任何模块和可用的操作
可选依赖库打包在 lib 文件夹内
可以将这些服务存档文件复制到 Axis2 存储库中(其中包含所有服务和模块),或通过 Axis2 所属的管理控制台进行更新。
Services.xml 文件描述其使用的消息接收者、所需的任何模块和可用的操作
可选依赖库打包在 lib 文件夹内
可以将这些服务存档文件复制到 Axis2 存储库中(其中包含所有服务和模块),或通过 Axis2 所属的管理控制台进行更新。
新客户机 API
Axis2 可以采用两种方式调用 Web 服务。ServiceClient API 是最简单的方法,但为用户提供的控制较少。OperationClient API 在调用期间提供了大量的控制。这两个 API 都内置了基本 In-Out 和 In-Only MEP。
Axis2 现在同时支持阻塞和非阻塞调用模型。非阻塞调用在设计用户界面时以及服务调用非常费时的情况下很有用。
用户现在可以为调用的不同路径选择不同的传输方法。例如,对于 In-Out 调用,用户可以按照以下方式进行处理:
使用 HTTP 发送消息,并使用相同的 HTTP 通道接收响应(使用一个双向通道传输方法)
使用 HTTP 发送消息,但使用不同的 HTTP 通道接收响应(使用两个双向通道传输方法)
使用 SMTP 发送消息,并使用 SMTP 接收响应(两个不同的传输方法)
这个功能可在选择交互的恰当传输时为用户提供最大的控制。
使用 HTTP 发送消息,但使用不同的 HTTP 通道接收响应(使用两个双向通道传输方法)
使用 SMTP 发送消息,并使用 SMTP 接收响应(两个不同的传输方法)
这个功能可在选择交互的恰当传输时为用户提供最大的控制。
可插入数据绑定
在纯 SOAP 级别上工作有时候比较麻烦,因此大部分用户更喜欢使用 Java 代码,而让框架处理 XML 和 Java 代码间的转换。这称为数据绑定。有很多数据绑定框架可用,用户会因为各种不同的原因而偏好使用某个框架。Axis2 支持目前可用的大部分数据绑定框架,而且没有任何限制。例如,Axis2 内置了对 XMLBeans、JAXB 和 JiBX 的支持,用户可以选择使用其中任何一个。任何其他数据绑定框架都可以方便地插入。
Axis2 还提供自己的简单数据绑定框架,称为 Axis2 Data Binding (ADB)。这就允许用户下载 Axis2 并使用它,而不用太多考虑数据绑定框架。由于 ADB 和 Axis2 内部元素之间实现了紧密的集成,可以预见,与其他框架相比,此框架的性能和生成代码维护方面都更具优势。
从以后的几个专题开始,我将分别介绍Axis2的不同实现方式。
参考资料:
http://www.jaron.cn/chs_scripts/26/2003-10/20031031162008-101283.HTML
http://www.vchome.net/dotnet/webservice/webservice4.htm
http://www.ibm.com/developerworks/cn/webservices/ws-wsdl/
http://www.ibm.com/developerworks/cn/webservices/ws-wsdl/
http://ws.apache.org/
http://ws.apache.org/axis2/
http://www.ibm.com/developerworks/cn/webservices/ws-apacheaxis2/
http://blog.donews.com/movele/archive/2006/06/15/916853.aspx