设为首页 收藏本站
查看: 3239|回复: 0

[经验分享] 使用 Apache Axis 和 Castor 创建 Web 服务

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-8-3 07:03:12 | 显示全部楼层 |阅读模式
最近的研究已经指出了通过 RPC 使用文档方式(Document-style)Web 服务的好处——它们对于XML更清晰、更自然,并且使对象交换更简单。然而,使用 Axis 部署文档方式服务可能就不那么容易了,因为 Axis 的数据绑定框架使用起来比较困难,并且不支持 XML-Schema 的某些流行功能,而更重要的是,缺少验证支持。本文论述了这些不利的方面,还通过提供循序渐进的教程,说明了如何集成 Axis 与 Castor 数据绑定框架,来组合 Axis 的 Web 服务技术与 Castor 的数据绑定功能,以创建一个两全其美的 Web 服务。
  三年以前,当 Web 服务进入技术社团的视野时,远程过程调用(RPC)接口是通用的实现。许多人了解了 SOAP,并且开始走上了熟悉的技术道路,比如用于公开服务器端数据和功能的 RMI、CORBA 和他们自己的自定义修改——这些复杂的、封闭的系统定义了如何以严格但仍然是高度编码的方式来发送和接收请求。编码 Web 服务的 RPC 方式通过提供自动方法来公开和调用方法而迅速地变得流行起来。但是,RPC 方式编码终究只是有限而不自然地使用了它的基础技术 XML。它相当于技术的错用————而在文档方式服务中,简单的 XML 独自提供了所需的全部表示。以最自然、最简单的方式保存技术标准是 Web 服务的真谛,文档方式就是这样的,在文档方式中,公开了接口,隐藏了后端和中间件系统,并且存在大量的动态发现、绑定和无尽的重用。

  本文将展示如何利用 Castor XML 绑定使 Apache Axis 环境中的文档方式 Web 服务更简单、更清晰、更直观。本文首先讨论了 Web 服务编码方法,并且解释了为什么 Castor 和 Axis 共同构成了一个好的解决方案。本文为创建和运行文档方式 Web 服务的所有步骤——从设计 schema 和服务到生成服务和客户端代码——提供了说明和解释。本文讲解了如何配置 Axis 来使用 Castor,并且介绍了开发人员在解决棘手的问题时可能遇到的“局限性(gotcha)”。

  文档方式的正反两面

  开发人员在开发 Web 服务时遇到的一项挑战是存在两种调用模型:RPC 和文档方式。有几篇好文章详细地论述了这两种模型之间的区别,但是下面的部分将简要地介绍这些不同之处,以给本文的其余部分作一个铺垫。

  RPC 方式编码之所以看起来有吸引力,是因为从概念上讲,它与开发人员已经使用了多年的其他实现架构(如 CORBA 或 RMI)是相同的。文档方式引起了人们的兴趣,但是 RPC 比较容易并且显示出技术相当简单,正因如此,文档方式经常受到冷遇。然而,过去的经验证明,快速开发是一项技术的关键,需要立即通过网络发送真实复杂的对 象。为了进行显示,发送字符串、整数抑或数组就可以了,但是现实世界使用复杂的数据结构和模型来编码数据。为了处理这种情况,SOAP RPC 实现支持复杂对象序列化和反序列化。只要对象遵循 Java Bean 规范,就可以将对象转换成 XML 文档,并且采用对开发人员透明的方式进行处理。这是非常有吸引力的——用几行简单的代码就可以通过网络发送真实业务数据对象,而无需考虑基础实现。

  
  RPC 的优点





  • 在一般的情况下,简单的请求/响应
  • 更易于使用,比如代表开发人员执行从XML到方法签名的映射
  文档方式的优点





  • 更丰富、更完整的数据描述
  • 更大的灵活性
  • 更好地适合工作流和异步处理
  • 通常更快速
  • 与现有的XML表示的互操作
  共同的制止因素





  • 解析器开发(在 DOM 或 SAX 中)
  • 从接收的文档到Java值对象的自定义、冗长的内部映射



  但是反过来说,通过 RPC 使用复杂对象也有缺点。这种方法常常产生集成问题。一种实现的序列化可能与另一种实现的反序列化不相匹配,因为用于 XML SOAP 编码过程的 Java Bean 的定义不明确。开放技术突然暴露出一个大的缺陷——Apache SOAP 在处理 .NET 时遇到麻烦,原因在于它们的实现之间的差异,因而迫切需要更加开放的服务。

  文档方式很好地融合了定义明确的结构和互操作性。这是通过用于定义复杂对象的标准  XML-Schema 实现的。与 SOAP 编码比较起来,XML-Schema 是一种严格而容易理解的标准,可以用于定义结构。XML-Schema 在定义复杂结构方面具有很大的灵活性,并且同时确保了Web服务的所有承诺——语言、平台、环境和传输中立(在使用通用应用程序编程接口的情况下)。

  文档方式获得了 XML-Schema 的所有优点,看来似乎能够解决所有的 Web 服务难题。然而,开发人员在选择文档方式时必须进行权衡。文档方式的一个不利的方面是增加了复杂性。开发人员会意外地发现,需要进行艰难的工作来解析 XML 文档和执行必要的转换,以载入其他数据 bean 和带有输入数据的方法请求。这对于服务器和客户端来说都是适用的。它意味着编写自定义 SAX 处理器,而使用和维护 SAX 处理器都特别困难。

  正在发展的解决方案:Apache Axis

Apache Axis是最流行的Web服务工具包之一。Axis支持RPC和文档方式服务,因此,它看来似乎是文档方式服务的真正开端。在使用文档方式服务时,您仍然 需要以某种方式处理输入的XML数据。Axis提供了一个方便的工具来帮助完成此项艰苦的工作,这个工具名为WSDL2Java。WSDL2Java不仅 可以为您的方法生成客户机和服务器的代码存根,而且可以生成实际bean,来对用XML-Schema定义的模型中的数据进行建模。然后, WSDL2Java将从XML中自动载入这些bean。通常这个过程称为数据绑定,它是XML-Schema背后的运动的支柱。WSDL2Java显得有 一些特异,但是往往它帮助事情的进展。很明显,这样的一个工具是非常有用的,但不幸的是,它并不是客户端存根生成的终结技术。它还面临着一些实际的问题:




  • WSDL2Java 陷入了大多数技术所遭遇的陷阱,也就是利用 schema 支持迎头赶上(playing catch-up with schema suppor)。编写一个工具,让它可以正确而完整地处理这些非常复杂的XML-Schema标准并不是一件小事情。就其本身而言,这代表了和 Axis 同样困难的工作。WSDL2Java在这方面显得不够,有缺陷,并且没有对许多 XML-Schem 特征提供完全的支持。例如对属性组和选项组的支持。但是这些地方正在改变,因为对WSDL2Java所做的工作也在继续。然而,编写和维护如此复杂的代码并不是 Axis 所看重的,并且,WSDL2Java将继续推进迎头赶上的策略,以满足独立数据绑定解决方案的功能。
  • 另外一个问题和第一个问题有关。WSDL2Java 生成的代码缺少 XML 验证(lacks XML validation)能力。当您开始使用XML文档的时候,验证是非常重要的,而且 XML-Schema 允许验证过程自动发生。然而,WSDL2Java 还没有一个机制来完成这一工作。
  • 字符串的序列化和反序列化接口不是直观的(not intuitive)。如果您的 XML 对象使用的是 WSDL2Java 的数据绑定代码,选择就是,您将需要在某个时候将对象编码或者解码为XML字符串。虽然这对 WSDL2Java 的生成对象来说是可行的,但却并不是一件容易的事情。需要安装一个庞大的框架,并且有可能出现许多头疼的事情,虽然它看起来好象是一项简单的任务。
  开 发社区对使用Apache Axis有一些复杂的反映和困惑,还有另外一个原因:开发社区是从 Apache Axis 的 beta 测试阶段开始伴随它一起壮大的,经历了 Apache Axis 发展的整个过程。需要了解的莫名其妙的工作区和配置机制随着版本的更新而不断变化。这就是开发代码主体的现实。最初,当 Axis一开始出现,重点关注的是 RPC Web 服务。因为这个原因,对RPC服务的支持是最多的,并且它的接口对于开发人员来说更稳定同时也更有名。直到现在,文档方式的文档、示例、Axis的样本配 置都是有限的。随着多种使用文档方式的内部配置选项(如包、文档或者消息)的出现,开发人员在建立它们自己的文档方式的服务时要经历更多的决策和复杂性。 然而,这些配置方面的困难并未形成大的障碍,无论如何,使用 RPC 仍然是调用 Web 服务的一种快速而便利的方法。当然,Axis还在不断的发展,这个困难将自动解决。不过,下面我们将一步一步地讲解如何使用文档方式的服务,您将会发现这 并不很难。

  Axis 和 Castor:皆为最优

Castor 是一个独立的 XML 数据绑定包,提供了从 XML-Schema 到 Java 对象的映射。这些 Java 对象看起来很像bean,但是可以编组(marshal)或者解组(un-marshal)为XML字符或者流,更重要的是可以对原始的Shcema进行 验证。Castor是一个开放源码的工作,遵循了开放的Web服务技术。这得到了一个非常活跃的开发组织的支持,因此,产生了大量的信息和 Web 内容,使得开发人员可以更有效的利用这些技术。


  我们在 Apache Axis 和 WSDL 不足的地方用 Castor 来构建所有级别的最优解决方案。我们将获得诸多好处,直观的数据绑定接口,更完全支持的 schema 实现,同时还利用了 Axis 框架的所有 Web 服务能力。图1显示了 Axis 和 Castor 之间的关系。

  图1. 在我们的解决方案中 Axis 和 Castor 之间的关系

http://www-900.ibm.com/developerWorks/cn/webservices/ws-castor/diagram.gif


  必备知识

  本文的读者是熟悉 Web 服务和相关的创建和部署技术的媒介 Java 开发人员。如果您可以编写基本的 WSDL 并使用 Axis 来部署一个服务,那么您就具备了阅读本文的预备知识。同样,本文假定读者掌握 XML 和 Schema 的知识。所有的代码都是使用 WebSphere Studio Application Developer 和 WebSphere Application Server versions 4.0.4、4.0.6 来开发、测试和部署的。也可以很轻松地用其他的开发和部署环境、库来进行替换,并且能获得同样的效果,但是,在本文中我们集中于这些环境。

  获得最新的 Axis 和 Castor

要构建和运行这个项目,您需要有 Apache Axis 和 Exolab 的 Castor。从 http://www.castor.org 可以很容易地得到 Castor 以及下载和安装指南。要获得 Apache Axis 相对来说难度更大一些,但也不难到哪儿去。在写作本文时,使 Axis 和 Castor 可以互操作的代码还不在发布的 beta 版本中,只能在CVS中得到。到读者阅读本文时,这一功能将很可能已经在最新发布的JAR中了。然而,在此之前,要获得最新版本的 Axis 以及这个项目所需的 org.apache.axis.ser.CastorSerializer 和 Deserializer 代码,最好的方法是从 CVS 获取,或者下载一个最新测试版(nightly build),这两种方式在http://ws.apache.org/axis/cvs.html上都有。按照这里介绍的方法来下载和构建一个Apache Axis的副本,比想象中的会更容易一些,这要感谢Apache Ant的构建架构。


  在 WebSphere 中启用 Axis

这个项目的样本环境是 WebSphere Application Server V4.0.4。在 WebSphere 或者其他 Java 容器安装 Axis 不会太难,但是正确地执行这些步骤仍然很重要。关于如何进行操作的指南在 Apache Axis 文档中(请参阅参考信息),您也可以在本地 CVS 检验版(checkout)或最新测试版(nightly)中的 /xml-axis/java/docs/install.html 中找到。


  如果您使用 WebSphere Application Studio V5.0,您可能会遇到一个“局限性”,这个局限性是关于 WebSphere Application Developer V5 上安装的环境和您试图与 Apache Axis 一起使用的环境之间的 JAR 冲突的。如果您遇到了这些问题,可以尝试这个快速修复(quick fix):在测试服务器的服务器配置中,将环境选项面板(Environment Options)系统属性(-D property)的“com.ibm.ws.classloader.warDelegationMode”设置为 false 。操作步骤如下:Server perspective > the server you are using for our example > Environment Options > System Properties > Add....

  定义 Schema 和服务

  要开发Web服务,您需要有一个 Schema,它表示两个部分,一个部分是您将要使用的数据,另一个部分是描述您将要公开的方法的的服务描述。讲解如何编写一个 XML-Schema 或者 WSDL 不在本文的讨论范围之内,不过在别的地方可以找到关于如何完成这一工作的文档。

  为了达到本文的目标,我们将创建一个示例服务:StockQuote服务。

  为您的数据定义 Schema:StockQuote.xsd

您的服务所需要的第一件事情就是用 XML-Schema 描述您的数据模型。在清单1中展示了将用在 StockQuote 服务中的简单数据模型,它应该是自解释的。


清单1. StockQuote服务的数据模型StockQuote.xsd























































  除了定义元素和 complexTypes 来代表您的数据模型之外,您还必须定义接口的输入/输出。这些就是Web服务将公开的方法,并且将在 WSDL(下一步讲解如何创建 WSDL)中进行指出,如清单2所示:

清单2. StockQuote.xsd的StockQuote服务的方法签名

































  为您的服务定义 WSDL:StockQuote WSDL

接下来,您必须为您的 Web 服务创建一个 WSDL 文件。您可以采用标准的方式来完成这一工作,但是这里有几个地方需要重点关注。首先,注意清单3中用黑体突出显示的部分。在标准方式中,您是用与您的数据模型相关联的 URI 来定义“types”命名空间前缀。其次,您将所需的独立 Schema 文件(StockQuote.xsd)导入 WSDL。最后,您在 WSDL 的消息声明中使用了“types”命名空间。为什么做这些工作显得很重要?因为 Castor 天生就不支持在文件中嵌入  节点,在本例中即为 WSDL 的  部分中的   节点。我们发现,像这样使用外部文件来定义您的数据模型和方法,不仅清晰、易于维护,而且更重要的是,它容许 Castor 和其他工具直接与您的文件形式的 Schema 进行交互。


清单3. StockQuote 服务的 WSDL 文件








































. . .


  这里惟一要提请注意的事情就是将 WSDL 设置为使用文档方式编码。注意清单4中用粗体突出显示的部分,它是 WSDL 的继续。这些部分将告诉 WSDL 以及 WSDL2Java,您使用的是文档方式的Web服务,并且您将生成文档方式(非 RPC)的服务请求。

清单4. StockQuote 服务的 WSDL 文件(续)









































  生成所需的代码和存根

  既然您已经准备好了您的服务定义和 Schema,这样就可以着手于 Axis 和 Castor。Axis 和 Castor 都需要生成一些代码,并且您可以把 Castor 生成的代码放在 Axis 生成的代码之上,这样就就可以做到“两全其美”了,既采用了 Axis 的 Web 服务客户端和服务器代码,有带有 Castor 的数据绑定。这第一个部分,将显示如何生成这些代码,下一个步骤将演示如何重新配置生成的映射,这样可以获得所期望的互操作性。

  使用 WSDL2Java 构建客户端和服务器端存根

WSDL2Java 生成 Java 类(用于数据模型中的对象的数据绑定)、客户端和服务器存根代码(用于连接您的方法)、以及服务绑定信息(用于 Axis 服务器)。我们将继续使用后面的两个部分:存根和服务绑定,而用 Castor 生成的代码来替代数据模型代码。但是要完成这一工作,首先必须运行 WSDL2Java 来生成我们将需要的存根和服务绑定。


  要使用 WSDL2Java 生成所需要的文件,可以运行以下命令:



%java org.apache.axis.wsdl.WSDL2Java -s "Web Content/StockQuoteService.wsdl"

--NStoPkg http://w3.ibm.com/schemas/services/2002/11/15/stockquote/wsdl=com.ibm.w3.services.stockquote

--NStoPkg http://w3.ibm.com/schemas/services/2002/11/15/stockquote=com.ibm.w3.services.stockquote

-o "Java Source"


  上面的命令将生成如清单5所示的文件。

清单5. WSDL2Java生成的文件




StockQuoteSOAPBindingImpl.java // a server-side service implementation template class,



StockQuotePortType.java // a server portType interface,

StockQuoteSOAPBindingStub.java // a server stub class,

where we'll write the getStockQuote method,

StockQuoteService.java // a client-side service interface,

StockQuoteServiceLocator.java // a client-side service implementation (the locator),



deploy.wsdd // the service bindings for the Axis server,

undeploy.wsdd



_quote.java // plus the classes to represent the data model,

ChangeType.java // which we will be replacing with the ones generated

LastTradeType.java // by Castor.

. . .


  当您在 WSDL2Java 中使用命令来生成文件时,您提供了几个参数。NStoPkg 参数指定了 Java 包,用于您的 StockQuote.xsd 文件的不同的命名空间,这将被 WSDL2Java 自动从 WSDL 文件加入进来。下一步,当您运行 Castor 来生成数据模型类,您可以使用同样的映射。对于 WSDL2Java 还有一些可选的额外参数,在本文中没有讲述,那将不使用 wrapped 的方式。这一个选项可以通过添加“-W”命令行来指定。在 WSDL2Java 中,wrapped形式意味着什么呢?它控制了 WSDL2Java 是如何生成方法客户端和存根。对于一个文档形式的服务,通过 -W 选项来指定不使用 wrapped方式,这将映射到一个方法,类似于下面用 StockQuoteSOAPBindingStub 类生成的:

  public GetStockQuoteResponse getStockQuote(GetStockQuote gsq)

  换句话说,在 StockQuote.xsd 文件中定义的整个  元素,将作为一个单独的 bean 传递给您的方法,在 bean 中有三个字段,如清单2所示。另一方面,对于一个标准的 wrapped方式的服务(也就是在这个示例中生成的),它将映射到如下的一个方法:

  public Quote getStockQuote(String symbol)

  本文中将使用 wrapped 形式,这种形式让我们觉得更易于阅读,这样也可以免于书写额外的代码。

  使用 Castor 生成数据绑定

目前,我们可以继续我们的工作,使用 Castor 生成数据模型绑定,来替换 WSDL2Java 所创建的。因为 Castor不是特定于 Web 服务的,它是直接使用 XSD 文件,而不是 WSDL 文件。因此,可以使用下面的命令,将 XSD 文件传递给它:


  %java org.exolab.castor.builder.SourceGenerator -i "Web Content/StockQuote.xsd"

-package com.ibm.w3.services.stockquote

-nomarshall

-dest "Java Source"

-f



  您使用命令行,并传递参数给 Castor。参数 -package 是对应于 WSDL2Java 的 NStoPkg 参数。参数 -nomarshall 告 诉 Castor 不要在所生成的 bean 中产生编组(marshall)方法(marshall、unmarshall、validate)。在您的示例中,这些方法是不必要的,因为 Castor Serializer and Deserializer for Axis 是直接使用 Castor Marshaller 和 Unmarshaller 类,这可以实现同样的目的,所以,我们使用参数来关闭它。如果您计划使用这些对象作为一个大系统的一部分,也可以打开这个参数。参数 -f 仅仅告诉 Castor,在没有提示的前提下去覆盖所有现有的文件。如果您注意到了这一点,您将清楚,这将覆盖那些在前面步骤中由 WSDL2Java 所生成的一些数据模型 bean。但是不用担心,因为您不用这些文件,所以这将不是一个问题。

  Castor 其余的选项在 castorbuilder.properties 文件中指定。大部分属性都不重要,但是,有一个很重要的设置:javaclassmapping设置。

  # Java class mapping of 's and 's

#

org.exolab.castor.builder.javaclassmapping=element



  这个设置决定了 Castor 如何从您的 Schema 中生成类。根据您如何编写您的 Schema,您也许想使用 element 或者 type。两者的区别是 element 方法为所有的 complexType 类型的元素生成类。对于所有的顶级  会生成抽象类。顶级 类型的 Schema 中的元素都将为之生成一个类,这个类继承了

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-93418-1-1.html 上篇帖子: 四大开源协议比较:BSD、Apache、GPL、LGPL 下篇帖子: Apache与Tomcat整合 (网络)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表