IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  WebSphere  >

使用 WebSphere Studio 进行自顶向下的 Web 服务开发

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Jeffrey Liu (jeffliu@ca.ibm.com), 软件开发人员, 多伦多实验室,IBM
Lawrence Mandel (lmandel@ca.ibm.com), 软件开发人员, 多伦多实验室,IBM

2004 年 3 月 01 日

本文章阐述了如何使用自顶向下的方法来设计和编码您的 Web 服务,这样将具备 Web 服务一个最大的优点:互操作性。文章将向您演示如何使用 WebSphere Studio V5.1 中的 Web 服务工具,包括 WSDL 编辑器和验证器。

本文章阐述了如何使用自顶向下的方法来设计和编码您的 Web 服务,这样将具备 Web 服务一个最大的优点:互操作性。文章将向您演示如何使用 WebSphere Studio V5.1 中的 Web 服务工具,包括 WSDL 编辑器和验证器。

引言


许多被 Web 服务激发起兴趣的开发人员早就开始编写一些简单的服务作为组织之间或者个人使用。这些开发人员由于不熟悉 Web服务技术与开发的复杂性,在大部分服务代码实现上都要依赖于工具。在这样的情况下,Web 服务的开发和使用全部都是由一名开发人员或一个小组完成。服务运行正常,不过由于编码生成工具存在一些问题,所以达不到 Web 服务的基本目标:互操作性。本文将讨论自顶向下 Web 服务开发的优点,同时还将向您演示如何使用 IBM WebSphere Studio V5.1工具来创建 WSDL 文档,并从这些文档生成可互操作的 Web 服务,然后对您的 Web 服务进行单元测试。





回页首


什么是 WSDL 及如何使用 WSDL?


WSDL(有时发音为 wiz-dul)或者 Web服务描述语言(Web Services Description Language),是一种 XML 元语言,用来描述关于Web服务的每件事情,从连接到服务的方法再到服务将返回的信息的类型。WSDL文档详细地指定了客户端可以用来与服务及服务的访问点进行交互的操作。WSDL 文档所允许的内容要受到 WSDL 规范的约束。这个描述文档为想要使用特定的服务来获取关于该服务的所有信息的客户端提供了一种标准方法。要找到使用 Web服务的方法并不用与发布 Web服务的组织联系,所有信息都可以从与服务相关的 WSDL 文档中获得。WSDL文档甚至还可以用来为将要使用服务的客户端生成框架代码。

由来自许多不同组织或公司(包括 Sun,Microsoft,Oracle 和 IBM)的人员所组成的一个协会 Web服务描述工作组管理着 WSDL规范。这个组的目标就是维护和发展 WSDL开放标准,从而提供一种平台独立的方法来描述 Web 服务。

  Web服务互操作性(WS-I)组织在其基本概要文档中为创建可互操作的 Web服务提供了最佳实践。基本概要包含了一些编写描述可互操作的 Web服务的 WSDL 文档的指导原则。确保您的 Web服务是可互操作的的最好方法就是首先创建一个遵守基本概要的描述文档,然后从遵守基本概要的 WSDL文档中生成您的服务。





回页首


自顶向下的 Web 服务开发的好处


自底向上的方法是开始开发 Web服务的最快也是最简单的方法。通过使用自底向上的方法,开发人员可以用任何高级编程语言(比如 Java TM和 C#)编写服务实现,他们还可以获得一些工具来生成描述服务的WSDL文档并将服务部署到服务器上。这种方法普遍用在一些自己组织内部有遗留系统及应用程序并且想让它们相互通信的公司之中。Web服务构建在现有基础构架的顶层,因而在组织内公开。在这种情况下,快速的自底向上的方法可以工作良好。一个公司既创建服务同时又使用服务,而且由于服务的所有客户端都是已知的,所以开发环境是可控的。由于服务和客户端都可以使用同一组工具来创建并且在同一个平台上运行,所以就没有必要那么担心互操作性方面的问题了。

当使用自底向上方法所开发的 Web服务因供运行在不同平台上的其他公司和消费者外部使用而公开时,或者当一家公司收购了另一家公司并且现在必须将第二家公司的系统与自己公司的系统合并时,互操作性问题就开始显现了。在这些情况下,当创建服务时并不知道该服务的所有可能的客户端,因而这种变化就引起互操作性问题。互操作性问题源自生成 WSDL 文档的工具。由于 WSDL规范中的模糊,所生成的 WSDL文档中可能会包含文档中所允许的特定于平台的信息。根据定义,特定于平台的 WSDL文档是不可互操作的,并且违背了 Web 服务的真正目标。

 Web服务要达到其基本目标,做到无愧于对它的吹捧并且进入计算主流,那他们就必须是可互操作。为了实现这一目标,开发人员就必须舍弃用工具生成 WSDL文档的方便性。在使用自顶向下的方法时,开发人员首先做的是编写一个 WSDL文档。一旦编写好了服务的描述,就可以由开发工具来生成服务的存根代码。接着,开发者就编写 Web服务的实现,并创建到任何现有体系结构的连接。通过您亲自编写 WSDL文档,而不依赖于有平台倾向性的工具,您就可以完全控制 WSDL文档,并且文档可以以标准的方式进行编写,这样它就能够为任何 Web 服务平台所理解。由于 WSDL文档是平台独立的,所以接着就可以生成任何语言的存根代码(前提是有工具可以这样做)。WSDL2Java 就是 Apache Axis中的一种可用的工具,它可以从 WSDL 文档创建 Java存根代码。

由于自顶向下方法消除了 Web服务中互操作性问题的主要根源,因此它是非常有利的。按照这种方法来开发 Web 服务需要我们努力去实现 Web服务实现之间的真正互操作性。下面的部分示范一个场景,在这个场景中,使用自底向上方法创建的服务存在互操作性问题,而使用自顶向下方法创建的同一个服务却没有这样的问题。





回页首


比较自顶向下和自底向上的 Web 服务开发的用况场景


由开发工具生成的 WSDL文档存在的问题就是,源于工具的错误会传播到Web 服务的顾客中去。服务的 WSDL文档就是它与它的客户端之间的契约。它定义了 Web 服务的术语及其使用。WSDL文档中的错误在期待的行为方面会误导 Web服务的顾客。这个用况场景对采用自底向上方法开发的地址簿 Web服务与采用自顶向下方法开发的同一个 Web 服务的互操作性进行了比较。





回页首


使用自底向上方法开发 echo 消息 Web 服务


由四个 Java 类组成: EchoMessage.javaMessage.javaRequestMessage.javaPhoneNumber.java。它们分别如图1,2,3,和4中所示:


图 1. EchoMessage.java
图 1. EchoMessage.java

图 2. Message.java
图 2. Message.java

图 3. RequestMessage.java
图 3. RequestMessage.java

图 4. ResponseMessage.java
图 4. ResponseMessage.java

EchoMessage.java有一个方法 getClassName。此方法接受消息实例作为输入,然后返回该实例的全限定 Java 类名作为输出。 Message.java本身就是一个抽象类,它有两个具体的实现。这两个实现阿分别是 RequestMessage.java 和 ResponseMessage.java。因此,方法 getClassName所期待的结果就是 com.example.RequestMessage或者 com.example.ResponseMessage。图 5 展示了描述 echo 消息 Web 服务的相应 WSDL文档,它是使用 Apache Axis 1.0 生成并部署的。


图 5. 使用自底向上方法创建的 WSDL 文档
图 5. 使用自底向上方法创建的 WSDL 文档

在 WSDL 文档的 XML Schema 类型定义部分,有一个为 com.example.Message定义的抽象复杂类型。其中并没有 com.example.RequestMessagecom.example.ResponseMessage这两个派生类型的定义。缺少这两个派生类型是一个互操作性问题,因为抽象类型是不能出现在 XML实例文档中的。抽象类型必须由它们的派生类型来代替。使用像Microsoft Visual Studio .NET 甚至 Apache Axis 本身这样的工具所创建的 Web服务客户端在调用这个 Web服务时就会存在问题,因为由于他们并不知道派生类型是什么。使用自底向上方法创建的echo 消息 Web 服务不是可互操作的,因为它的WSDL 文档不够完整。





回页首


使用自顶向下方法开发 echo 消息 Web服务


使用自顶向下创建的就不会存在上一部分所阐述的互操作性问题了。全部所需的 XMLSchema类型定义都可以通过创建 WSDL 文档来指定。使用如图 6 所示的 WSDL文档就可以创建相同的 echo 消息 Web 服务。 echo 消息 Web服务使用这个描述文档与其他 Web服务客户端很好地互操作。图 7展示了一个样本请求和响应消息。


图 6. 使用自顶向下方法创建的 WSDL 文档
图 6. 使用自顶向下方法创建的 WSDL 文档

图 7. echo 消息 Web 服务中的样本请求和响应消息
图 7. echo 消息 Web 服务中的样本请求和响应消息

下一部分将演示如何使用 WebSphere Studio 5.1 工具来编写 WSDL文档,再从 WSDL 文档构建一个 Web 服务,然后测试该Web 服务。





回页首


创建 WSDL 文档


只要您是用 WebSphere Studio进行开发,您的第一步就是要创建一个项目:

  • 选择 File => New => Project
  • 选择左侧的 Web和右侧的 Dynamic Web Project,然后单击 Next
  • 输入 AddressBookWeb的项目名并单击 Finish。如果系统提示您切换到 Web透视图,单击 OK。
  1. 使用自顶向下方法创建 Web 服务的第一步就是创建我们的 WSDL 文档。
    选择 AddressBookWeb项目,右键单击它,就会出现一个上下文菜单,选择 New => Other
    选择左侧的 Web Services和右侧的 WSDL。单击 Next
    将名称更改为 AddressBook.wsdl并单击 Next
    namespace更改成 http://example.com/AddressBook以及将 Definition名更改为 AddressBook
    确保 WSDL 和 XSD 前缀被选中,选择 soap Prefix并单击 Finish

  2. 现在 WSDL编辑器就随着新创建的WSDL 文档一起打开了。选择 Graph tab

  3. 我们将首先定义该服务。在 Services下右键单击并选择 Add child => service。命名 GetInfoByNameService服务并单击 OK
    我们必须创建定位服务的端口。右键单击 GetInfoByNameService并选择 Add Child => Port。命名 SOAPPort端口并单击 OK
    图 8. 创建服务
    图 8. 创建服务
  4. 我们需要为服务设置具体的绑定信息。我们首先仅设置绑定,以后再填写其详细内容。图 9展示了 Specify Binding 向导。
    右键单击 Port并单击 Set Binding。将绑定名改成 GetInfoByNameBinding并单击 Finish.


    图 9. 创建新的绑定向导
    图 9. 创建新的绑定向导
  5. 绑定需要引用操作的抽象定义。操作是包含在 portType中的,因此我们需要为绑定设置 portType。
    选择位于顶部 Show Bindings按钮(在 WSDL编辑器右上角)。 showBindings.jpg现在绑定将会显示在 graph 视图中。
    右键单击 GetInfoByNameBinding并选择 Set PortType。确保 Create a new Port Type被选中,并将端口类型命名为 AddressBookPortType
    单击 Finish

  6. 我们现在能够根据所给名称指定操作来获取地址簿信息。右键单击 AddressBookPortType并选择 Add Child=> Operation
    将操作命名为 GetInfoByName并单击 OK

  7. 我们将指定这个操作的输入。这是请求输入所请求的地址信息的名称的地方。
    右键单击 GetInfoByName并选择 Add Child=>Input

  8. 现在我们能够指定需要输入操作的信息。单击 Input并选择 Set Message。确保 Create a new message被选中,将消息名设置为 GetInfoByNameRequest并单击 Finish
    右键单击 GetInfoByNameRequest并选择 Add Child => part。将该部分命名为 Name并单击 OK

  9. 现在我们将为操作添加输出或返回信息。右键单击 portType 操作 GetInfoByName并选择 Add Child => Output

  10. 我们需要设置返回的输出。右键单击 Output并选择 Set Message。确保 Create a new message被选中,将消息名设置为 GetInfoByNameResponse并单击 Finish
    右键单击 GetInfoByNameResponse并选择 Add Child=>part。将该部分命名为 AddressBookInfo并单击 OK

  11. 现在我们准备创建一个单向操作来将信息添加到我们的地址簿。这是一个需要输入但是不输出任何东西的操作。右键单击 AddressBookPortType并选择 Add Child=>operation。将该操作命名为 SaveInfo并单击 OK

  12. 我们需要添加一个输入。右键单击 SaveInfo并选择 Add Child=>input

  13. 右键单击 SaveInfo下的 input 并选择 Set Message。确保 Create a new message被选中,将消息名称设置为 SaveInfoRequest并单击 Finish
    右键单击 SaveInfoRequest并选择 Add Child=>part。将该部分命名为 AddressBookInfo并单击 OK
    您的 WSDL 文档(带有隐藏的绑定)现在应该看起来如图 10 所示。


    图 10. 带有隐藏的绑定的当前 WSDL 文档
    图 10. 带有隐藏的绑定的当前 WSDL 文档
  14. 现在,我们将创建自定义元素,这些元素用作我们操作中的输入和输出参数。在 Types下单击并选择 Add Child=> Add Schema
    图 11. 将 Schema 添加到文档中
    图 11. 将 Schema 添加到文档中
  15. 双击 Types 部分 Schema 旁边的箭头,这将会打开 Schema 编辑器。
    图 12. 选择 Schema 旁边的箭头来编辑它
    图 12. 选择 Schema 旁边的箭头来编辑它
  16. 首先,我们将创建一个复杂类型来控制地址信息。右键单击 schema element并选择 Add Complex Type。将元素名更改成 Address。右键单击 Address并选择 Add Complex Content
    右键单击 complex content并选择 Add Element。将元素名更成 Street
    按照先后顺序为 City, Province, PostalCodePhoneNumber添加元素。
    图 13. 添加一个全局复杂类型
    图 13. 添加一个全局复杂类型
  17. 接下来我们将要创建一个复杂类型来控制名称信息。右键单击 Complex Types并选择 Add Complex Type。将复杂类型的名称更改为 Name
    右键单击  Name并选择 Add Complex Content
    右键单击 complex content并选择 Add Element。将名称更改为 FirstName
    添加第二个元素并将名称更改为 LastName

  18. 我们现在需要一种具体方法来引用我们的复杂类型。我们将在Schema中创建全局元素。我们需要的第一个元素就是我们的姓名。右键单击 Schema并选择 Add Global Element
    将元素的名称更改为 Name.
    通过下拉菜单,将元素类型更改为 tns:Name
    图 14. 添加全局元素
    图 14. 添加全局元素
  19. 我们需要的第二个全局元素是为包含姓名及地址的地址簿信息所创建的。
    右键单击 Global Elements并选择 Add Global Element
    将新元素的名称更改为 AddressBookInfo
    单击 AddressBookInfo并选择 Add Local Complex Type
    单击 complex type并选择 Add Element.
    将该元素命名为 Name并选择类型 tns:Name
    为复杂类型创建第二个元素。将该元素命名为 Address并选择类型 tns:Address
  20. 现在我们有了所需的全不元素。单击编辑器右上角的箭头返回到 WSDL编辑器。 editorarrow.jpg

  21. 现在我们需要设置消息的各个部分来使用刚在 Schema 中定义的元素。图 15展示了Specify Element 向导。
    右键单击 GetInfoByNameRequest tns:Name部分。选择 Set Element。选择一个现有的元素。选择 tns:Name并单击 Finish
    将其他两个部分的元素设置为 tns:AddressBookInfo
    图 15. 为消息指定元素
    图 15. 为消息指定元素
  22. 现在我们所要做的就是填写绑定信息。Generate Binding向导如图 16 所示。
    WSDLEditor菜单中选择 Generate Binding Wizard。确保现有绑定的 Generate 内容被选中。选择 GetInfoByNameBinding。再选择 tns:AddressBookPortType。选择 Protocol: SOAP并将 SOAP Binding Options 设置为 document literal。确保 Overwrite existing bindinginformation 被选中并单击 Finish
    图 16. 在绑定向导中设置绑定信息
    图 16. 在绑定向导中设置绑定信息

  23. 我们应该检查一下 WSDL 文档是否有效。保存 WSDL 文档,然后在 Navigator 视图中单击它,从上下文菜单中选择 Validate WSDL File。您应该看到如图 17 所示的对话框,它表明 WSDL 文件是有效的。
    图 17. 验证成功后的消息窗口
    图 17. 验证成功后的消息窗口

祝贺您!您的服务定义已经完成了。

您可以在此查看所完成的 WSDL 文档.





回页首


构建并测试 Web 服务


  1. 调出向导选择对话框。从菜单中 File=> New=> Other.

  2. 启动 Web 服务创建向导。选择左侧菜单中的 Web Services和右侧列表中的 Web Service,然后单击 Next

  3. 图 18 展示的是 Web 服务创建向导。选择 Skeleton Java bean Web Service作为 Web 服务类型,取消选定 Start Web service in Webproject复选框并选中 Overwrite files without warning复选框。单击 Next
    图 18. Web 服务创建向导
    图 18. Web 服务创建向导
  4. 接受服务部署配置页面中的缺省设置。地址簿 Web 服务将会部署到 WebSphere V5.0.2 单元测试环境中的 IBM WebSphere V5.0.2 Web 服务引擎上。单击 Next

  5. 图 19 展示的是 Web服务选择页面。单击 Browse按钮找到 AddressBook.wsdl 所在位置。单击 Next
    图 19. Web 服务选择页面
    图 19. Web 服务选择页面
  6. 接受 Web 服务框架 Java bean 配置页面的缺省设置。单击 Finish。这样将会生成基于 AddressBook.wsdl的 Java 框架代码。

  7. 在调用地址簿 Web 服务之前,我们必须填入 Java 框架的执行。在编辑器中打开 /AddressBookWeb/JavaSource/com/example/GetInfoByNameBindingImpl.java 。如图 20所示修改这个 Java 框架。保存并关闭编辑器。
    图 20. GetInfoByNameBindingImpl.java
    图 20. GetInfoByNameBindingImpl.java
  8. 如有必要打开服务器视图。单击菜单 Window=> Show View=> Other...在 Show View 对话框中,展开服务器选项卡,选择 Servers节点并单击 OK

  9. 在服务器视图中,右键单击 server,这样就部署了地址簿 Web 服务,选择菜单项 Start

  10. 我们将使用 Web Service Explorer 来测试地址簿 Web 服务。要启动 Web Service Explorer,可以右键单击 /AddressBookWeb/WebContent/wsdl/com/example/AddressBook.wsdl,然后选择菜单项 Web Services=> Test with Web Services Explorer
    图 21. Web 服务浏览器
    图 21. Web 服务浏览器
  11. 单击 SaveInfo操作保存地址。输入如图 22 所示的值并单击 Go
    图 22. SaveInfo 操作
    图 22. SaveInfo 操作
  12. 要检索在上一步中保存的地址,可以在 Web Service Explorer 的导航器窗格中单击 GetInfoByName节点。输入 John作为名,输入 Doe作为姓。单击 Go调用操作。图 23 显示了包含调用操作结果的Status 面板。
    图 23. 包含调用 GetInfoByName 操作结果的 Status 面板
    图 23. 包含调用 GetInfoByName 操作结果的 Status 面板




回页首


结束语


互操作性是 Web 服务想要打开主流计算大门的钥匙。Web 服务的互操作性从描述关于服务的每件事情的 WSDL文档开始。自底向上 Web 服务开发的方法很快捷、很容易,但是会产生一些存在互操作性问题的服务。保持互操作性最好的办法就是遵循自顶向下 Web 服务开发的方法,并且从编写您的描述文档开始开发工作。WebSphere Studio 5.1 提供了一些用于编写 WSDL 文档的工具,可以从这些文档生成可互操作的服务并且对您新创建的服务进行单元测试。



参考资料



作者简介

Jeffrey Liu 是 IBM 多伦多实验室 WebSphere Studio Application Developer Web 服务工具小组中的一名软件开发人员。


Lawrence Mandel 是 IBM 多伦多实验室 WebSphere Studio Application Developer XML 工具小组的一名软件开发人员。Lawrence 同时还是 Eclipse Web Service Validation Tools 项目的一名委员。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款