了解如何使用 IBM® Rational® Application Developer 创建能接收包含附件(除消息主体中的正常内容外)的 SOAP 消息的 Web 服务。我们将使用一个简单的示例,在此示例中,服务将接收主体中的文本消息以及作为附件的文本消息、jpeg 文件和 zip 文件。
在本文中,您将使用 IBM Rational Application Developer(以下称为 Application Developer)集成开发环境(Iintegrated Development Environment,IDE)来创建服务和客户机,该服务将接收主体中的文本消息以及作为附件的文本消息、jpeg 文件和 zip 文件。此处提供该客户机的目的是为了演示如何将带附件的 SOAP 消息发送到 Web 服务,并通过示例说明连接到 Web 服务并向其发送消息的良好模式。
此练习中创建的大部分项目构件都是通过使用 Application Developer 工具自动生成的,不过用于生成其中两个项目的 WSDL 文件例外。尽管您可能希望通过使用 Application Developer 来提高效率,但仍然可以手动创建各个项目构件(只要您有足够的时间)。通过分析生成的各个构件,您可以了解发送带有附件的 SOAP 消息所需的技术。
在此练习中,我们将从一个 WSDL 文件着手,该文件描述能接收带有文本主体和文本、zip、.jpg 文件附件的消息。我们将使用该 WSDL 文件来创建服务和客户机项目;其中包含所需的所有代码,但为了说明一些其他的功能,我们将手动对代码进行一些改进。特别要注意,我们将向生成的构件添加一些代码,以向 Application Developer 控制台输出跟踪消息,从而能够了解系统的执行情况。此外,我们还将向服务应用程序添加一个 JAX-RPC 处理程序,以便演示如何使用一些简单的 SOAP Attachments API for Java™ (SAAJ) 代码来确认附件存在。该处理程序代码并不是必需的,但它说明了在应用程序有直接发送消息之外的其他要求时可用于提供其他消息处理的技术。
|
准备环境
此部分描述准备环境的步骤。
准备源代码
下载部分提供的 AttachmentsFiles.zip 文件包含了将在此练习中使用的六个文件:
- AttachmentIBM.wsdl——用于生成 2 个项目的 wsdl 文件。
- AttachmentIBMHandler.java——包含 SAAJ 代码的可选文件,可用于确认消息包含了附件。
- AttachmentIBMTest.jsp——这是另一个可选文件,其中包含调用我们创建的测试客户机的若干代码行。
- AttachmentIBMBindingImpl.java——实现 AttachmentIBM 接口的类,包含提供此操作功能的代码。此文件可在本练习中使用向导生成,但生成的版本并不包含所需的全部代码,因此这个版本中包含我自己的自定义代码,可以将其复制到生成的版本中。
- fed.zip——作为附件使用的示例 zip 文件。
- fed.jpg——作为附件使用的示例 jpg 文件。
将这些文件解压到一个文件夹中,如 C:\temp1,以便在此项目开发期间根据需要从此处将其导入到 Application Developer 中。
注意:如果将 fed.jpg 文件和 fed.zip 文件放在 c:\temp1 之外的其他目录中,则必须更改 AttachmentIBMTest.jsp 中对这些文件的引用。
启动 Application Developer
启动 Application Developer,最好使用新工作区。打开后,请执行以下步骤启用 Web 服务工具:
- 选择 Window => Preferences => Workspace => Capabilities。
- 单击 Web Services Developer 和 Advanced J2EE。
启动服务器
在 Servers 选项卡上,右键单击 WebSphere Application Server v6 并选择 Start。
|
从 WSDL 文件创建服务
此部分描述创建服务的步骤。
为 Web 服务创建一个空白 Web 应用程序项目
- 选择 File => New => Dynamic Web Project,以打开 New Project 向导。
- 在 New Dynamic Web Project 对话框中,在 Name 字段中键入
AttachmentService
,接受其他字段的缺省值,并单击 Finish,如图 1 中所示:
图1. 为 Web 服务创建一个空白 Web 应用程序项目
将随即创建具有图 2 中所示的结构的新 Web 项目:
图 2. 新 Web 项目
在继续进行服务开发前,请执行以下步骤,以将新项目部署到 WebSphere 测试服务器:
- 在 Servers 选项卡上,右键单击 WebSphere server,然后选择 Add and Remove Projects。
- 选择 AttachmentServiceEAR 并单击 Add,然后单击 Finish,如图 3 中所示:
图 3. 可以部署的项目
生成新项目中的 Web 服务组件
现在需要将新项目 AttachmentIBM.wsdl 添加到上面的项目中,以便能将其用于生成项目的 Web 服务组件。为此,请执行以下步骤:
- 展开 AttachmentsService 项目,右键单击 WebContent 并选择 Import => File System => Next。
- 在 Import 对话框中,浏览到解压缩示例文件的文件夹中。在对话框左侧,单击所选择的文件夹名称(但不要单击复选框)。将在右侧显示文件的内容。选中 AttachmentIBM.wsdl 并单击 Finish,如图 4 中所示:
图 4. 可以部署的项目
AttachmentIBM.wsdl 包含生成 Web 服务和使用该服务的客户机所需的所有信息。让我们对此文件的内容进行一下分析。双击 AttachmentIBM.wsd,以在 Application Developer 文本 XML 编辑器中打开它,然后单击 Source 选项卡以查看代码。有两个部分对本练习特别重要。
清单 1 给出了一个消息定义,用于描述在清单 2 定义的 sendAttachments
操作中发送的消息的内容。此消息非常有意义,因为 JAX-RPC 将使用其确定组成实现 sendAttachments
操作的方法的签名的 Java 数据类型。
清单 1. 消息定义
|
通常,通过此定义将得到这样的方法签名:其第一个参数声明为 Java String
,所有其他参数都声明为 Java 字节数组。但 wsdl 的 bindings 部分包含将更改此设置的信息,如清单 2 中所示。
清单 2. wsdl bindings 部分
|
bindings 部分包含确定消息内容特征的 MIME 声明。
第一个 mime:part
指 SOAP 消息的主体。会将其作为典型的 literal
编码样式元素处理。
第二个 mime:part
部分将消息的 textAttachment
部分的 mime 类型定义为 text/plain
。因为这样,JAX-RPC 会导致将第二个参数作为 Java String
而不是 Java 字节数组生成。运行时,SOAP 引擎将从 SOAPMessage 检索此 AttachmentPart
,并将其作为 Java String
传递给操作。
第三个 mime:part
部分将消息的 imageAttachment
部分的 mime 类型定义为 image/jpeg
。因为这样,JAX-RPC 会导致将第三个参数作为 Java java.awt.Image
而不是 Java 字节数组生成。运行时,SOAP 引擎将从 SOAPMessage 检索此 AttachmentPart
,并将其作为 Java Image
传递给操作。
第四个 mime:part
部分将消息的 zipAttachment
部分的 mime 类型定义为 application/zip
。因为这样,JAX-RPC 会导致将第四个参数作为 Java javax.activation.DataHandler
而不是 Java 字节数组生成。运行时,SOAP 引擎将从 SOAPMessage 检索此 AttachmentPart
,并将其作为 Java DataHandler
传递给操作。此附件的 mime 类型无法由 JAX-RPC 直接映射到 Java 类型。如果 mime 类型不为 JAX-RPC 知道如何处理的少数类型之一,则会将附件映射到 javax.activation.Datahandler
类,该类必须由操作进行显式处理。有关 mime 类型到 Java 类型的映射,请参见 JAX-RPC 文档。
现在,您已经了解了 wsdl 文件各个部分的含义,并知道了映射组件的预期行为,接下来让我们使用此 wsdl 创建项目中所需的 Web 服务构件:
- 关闭编辑器。
- 右键单击 AttachmentIBM.wsdl,然后选择 Web Services => Generate Java bean skeleton。
- 将随即启动 Web Service 向导。在 Web Services 对话框上,选择 Overwrite Files without warning 并单击 Next,如图 5 中所示:
图 5. Web Services 对话框
- 在 Object Selection 对话框中,接受缺省设置并单击 Next,如图 6 中所示:
图 6. Object Selection 对话框
- 在 Service Deployment Configuration 对话框中,接受缺省设置并单击 Next,如图 7 中所示:
图 7. Service Deployment Configuration 对话框
- 在 Web Service Skeleton Java Bean Configuration 对话框中,接受缺省设置并单击 Finish,如图 8 中所示:
图 8. Web Service Skeleton Java Bean Configuration 对话框
向导完成处理以后,您将注意到在项目中创建了几个新文件。Application Developer 会在 Java 编辑器中打开新建的 AttachmentIBMBindingImpl.java 类。在了解 AttachmentIBMBindingImpl.java 文件之前,让我们看看向项目添加了哪些文件。图 9 显示了 Project Explorer:
图 9. Project Explorer
向下逐层展开到 AttachmentService => JavaResources => JavaSource 文件夹,将看到其中创建了一个新包 ibm.attachment
。展开此文件夹,将看到两个新类:
- AttachmentIBM.java——这是经常被称为服务器框架的 Java 接口。它声明此 Web 服务中可用的各个方法,由服务器用于取消封送传入 SOAP 消息的内容。
- AttachmentIBMBindingImpl.java——实现
AttachmentIBM
接口的类,包含提供此操作功能的代码。生成的方法是空的,因为要由开发人员负责提供满足操作要求的代码。稍后,我们将在此处插入一些代码,以向 WebSphere 控制台输出一些消息,从而能监视此服务的测试执行情况。
展开 WebContent => WEB-INF 文件夹,将看到另外两个新文件:
- webservices.xml——此文件包含服务的定义。通过分析此文件,可以看到将 AttachmentIBM.java 作为服务端点接口的引用和将 AttachmentIBMBindingImpl.java 类作为服务实现 Bean 的引用。
- AttachmentIBM_mapping.xml——此文件描述从传入 XML 流到服务操作的方法签名中声明的 Java 类型的映射。此文件的内容相当晦涩,但构造这些映射的规则在 JAX-RPC 规范中进行了描述。
此外,对 web.xml 文件进行了一处更改,为 AttachmentIBMBindingImpl.java 类插入了 Servlet 声明,以便在运行时能由 SOAP 引擎进行调用,如清单 3 中所示:
清单 3. AttachmentIBMBindingImpl.java 类的 Servlet 声明
|
我们已经对 Web 服务生成向导的结果进行了分析,接下来让我们继续我们的练习。向导创建了 AttachmentIBMBindingImpl.java 文件,并在 Java 编辑器中将其打开。通常会在此时开始进行服务操作的实际实现的编码工作。不过,由于我们仅对传递附件感兴趣,因此将仅添加一个控制台消息,以显示消息主体的内容和一些有关我们从客户机应用程序向此服务传递的附件的信息(将在下一部分使用 Application Developer 向导生成此客户机应用程序)。将清单 4 中的代码添加到此类的 sendAttachments
方法(您可以自行键入,也可以从下载部分提供的 AttachmentIBMBindingImpl.java 文件中复制)。
清单 4. 向 sendAttachments 方法添加的代码
|
此类现在应该与以下所示类似:
图 10. 新的 AttachmentBindingImpl 类
保存并关闭 AttachmentIBMBindingImpl.java 文件。
向服务项目添加可选处理程序
尽管我们已经正式完成了这个服务,但接下来还要向项目添加一个新类,以演示传递给服务的两个文本消息中的一个实际上是作为附件传递的。我们将创建一个 JAX-RPC 处理程序来在服务器端解释传入请求消息,并使用 SOAP Attachments API for Java (SAAJ) 中的类对传入消息进行检查。我们定义的这个处理程序将查找 SOAP AttachmentParts,并在控制台显示所找到的任何部分的 mime 类型。
我们将使用 Application Developer 来创建基本处理程序,然后将添加检查 SOAP 消息的 SAAJ 代码。我们的处理程序的代码非常简单。可以键入以下所示的代码,或从随本文提供的文件进行复制粘贴。
让我们首先创建基类,并分析生成的代码:
- 在服务项目中,导航到 JavaResources => JavaSource 文件夹,并右键单击 JavaSource。
- 选择 New=>class,以启动 New Class 向导。
- 在 New Java Class 对话框中,键入
ibm.attachment.handler
作为包名称,键入AttachmentIBMHandler
作为类名称,然后单击 SuperClass 字段旁边的 Browse。 - 在 Superclass Selection 对话框中的 Choose a Type 字段键入
GenericHandler
。在 Qualifier 字段中,从javax.xml.rpc.handler
包选择 GenericHandler 类,然后单击 OK,如图 11 中所示:
图 11. Superclass Selection 对话框
- 回到 New Java Class 对话框,选中 Constructors from superclass,然后单击 Finish,如图 12 中所示:
图 12. 新 AttachmentBindingImpl 类
我们刚刚创建的处理程序只是一个框架,因此需要添加一些额外的代码,以实现我们希望提供的功能。用于派生我们的处理程序的 GenericHandler
具有调用处理程序时由 SOAP 运行时调用的方法。其中的 handleRequest
方法将在传入请求传递到 Web 服务前立即调用。这就允许 JAX-RPC 处理程序的开发人员在消息送达服务前进行任何其他消息操作或处理。在我们的例示例中,只是希望演示包含附件的消息。我们将使用数行简单的 SAAJ 代码来进行此工作:
- 首先,将清单 5 中的 Java import 语句添加的该类的顶部:
清单 5. import 语句
import javax.xml.namespace.QName; import javax.xml.rpc.handler.GenericHandler; import javax.xml.rpc.handler.MessageContext; import javax.xml.rpc.handler.soap.SOAPMessageContext; import javax.xml.soap.AttachmentPart; import javax.xml.soap.SOAPMessage; import java.util.Iterator;
- 将清单 6 中所示的代码添加到类的主体中,从而向类添加我们的
handleRequest
方法实现:
清单 6. handleRequest 方法
public boolean handleRequest(MessageContext mc) { System.out.println("entering handleRequest"); SOAPMessageContext smc = (SOAPMessageContext)mc; SOAPMessage sm = smc.getMessage(); Iterator attachments = sm.getAttachments(); if (!attachments.hasNext()) { System.out.println("No Attachments"); } else { System.out.println("Has Attachments"); while (attachments.hasNext()) { AttachmentPart attachment = ( AttachmentPart)attachments.next(); System.out.println("Attachment Type is: " + attachment.getContentType()); } } System.out.println("exiting handleRequest"); return true; }
您将发现,我们的简单处理程序将检查 SOAPMessage,查找
AttachmentParts
,并会输出所找到的任何附件的 mime 类型。 - 保存并关闭 AttachmentIBMHandler.java 文件。
现在已经向项目添加了处理程序,但还需要对项目进行配置,以在运行时使用该处理程序。需按照以下所示,向 webservices.xml 类添加一个 handler 部分,以实现此目标:
- 导航到 WebContent=>WEB-INF 文件夹,并右键单击 webservices.xml,然后选择 Open with => Web Services Editor。
- 进入 Handlers 选项卡,在 Handlers 部分单击 Add。
- 在 Class Browser 对话框中,在 Browse for a Java class 字段中键入
AttachmentIBMHandler
,从 Qualifiers 字段选择 ibm.attachment.handler 包,并单击 OK,如图 13 中所示:
图 13. Class Browser 中的 AttachmentIBMHandler
- 在有些早期版本的 Application Developer 中,编辑器包含一个软件错误,即使已将
Handler
类添加到文件中,也不会在 Handlers 部分显示。保存并关闭编辑器,接下来我们将了解添加过程的工作情况。 - 右键单击 webservices.xml 并选择 Open with => Web Services Editor,从而再次打开 webservices.xml 文件。
- 在 Handlers 选项卡上,应该看到此处理程序在 Handler 部分列出,如图 14 中所示:
图 14. 已添加了处理程序
- 关闭 XML 编辑器。
- 为了准确了解向 webservices.xml 文件添加了什么内容,我们将在文本编辑器中打开此文件。右键单击 webservices.xml,并选择 Open with => XML Source Page Editor。将会发现在
port-component
部分向文档添加了包含三行代码的 handler 部分,如图 15 中所示:
图 15. webservices.xml 的视图
- 关闭编辑器。服务项目现在已完成,应该与图 16 中所示类似:
图 16. 已完成的项目
发布到服务器
有时候,更改了项目的部署描述符后,服务器可能不会注意到这个更改。为了将更改部署到服务器,请转到 Servers 选项卡,右键单击 WebSphere server,并选择 Publish。发布需要一定的时间完成。
|
从 WSDL 文件创建客户机
现在已经完成了服务,接下来将生成客户机项目来测试新 Web 服务。可以使用 Application Developer 中的 Web Services Explorer 测试我们的 Web 服务,但生成的客户机项目中包含能作为 Web 服务调用模型的代码。此外,Application Developer Client Generation 向导生成的客户机项目还可作为客户机项目设计的一个不错的例子使用。
生成 Web 服务客户机组件
我们将使用与 Web 服务项目相同的 wsdl 文件来通过 Application Developer 工具生成新的客户机项目。
- 在 AttachmentService 中,右键单击 AttachmentIBM.wsdl,并单击 Web Services => Generate Client。在 Web Service Client 对话框中,从 Client proxy type 字段选择 Java Proxy,选中 Overwrite files without warning,然后单击 Next,如图 17 中所示:
图 17. Web Service Client 对话框
- 在 Web Service Selection 页中,接受缺省设置(所选定的 wsdl 文件)并单击 Next,如图 18 中所示。
图 18. Web Service Selection 页
- 在 Client Environment Configuration 页的 Client project 字段键入
AttachmentClient
,并接受 ear 文件的缺省设置。单击 Next,如图 19 中所示:
图 19. Client Environment Configuration 页
- 在 Web Service Proxy 页中,接受缺省值,并单击 Finish,如图 20 中所示:
图 20. Web Service Proxy 页
- 向导完成处理时,将在 Dynamic Web Projects 下看到新建的 AttachmentClient 项目。打开此项目,并展开所有文件夹,以确定向导生成的内容,如图 21 中所示:
图 21. 向导输出
JavaSource 文件夹下的 ibm.attachment
包中包含一系列重要的类:
- AttachmentIBM.java——这是表示服务本身的 Java 接口,提供了其操作的声明。
- AttachmentIBMBindingStub.java——这是实现
AttachmentIBM
接口的类。此类的代码绑定到 Web 服务,并调用 Web 服务。 - AttachmentIBMProxy.java——此类用于检索 Web 服务的实例。此类中的代码首先进行 JNDI 查询,以确定是否可以获得服务的实例。如果未找到服务,它将使用
AttachmentIBMServiceLocator
类来为其获得服务的实例。 - AttachmentIBMService.java——此 Java 接口定义用于查找服务的方法。它由
AttachmentIBMServiceLocator
类实现。 - AttachmentIBMServiceLocator.java——此类包含查找服务和返回 AttachmentIBM 服务实例的代码。
另一个有意思的文件 AttachmentIBM_mapping.xml 位于 WebContent => WEB-INF 下。此文件与 AttachmentService 项目中的同名文件具有相同的作用:描述从 XML 流到服务操作的方法签名中声明的 Java 类型的映射。同样,此文件的内容相当晦涩,但构造这些映射的规则在 JAX-RPC 规范中进行了描述。
添加测试 JSP 文件
测试 Web 服务前,还需要做最后一件事。需要提供使用生成的 AttachmentIBMProxy
与 Web 服务通信的代码。本练习随附的一个简单 JSP 文件提供了此功能。我们将说明将此代码导入到客户机项目的过程,另外还将给出代码,以便您能将其放入到自己的 JSP 中。
- 在 AttachmentClient 项目中,导航到 WebContent 文件夹,右键单击该文件夹,并选择 import => File System => Next。
- 在 Import 对话框中,浏览到放置示例代码的文件夹,并选择 AttachmentIBMTest.jsp 文件,然后单击 Finish,如图 22 中所示:
图 22. 向导输出
针对希望提供自己的 JSP 的情况,清单 7 中显示了我们在示例 JSP 中包含的简单代码:
清单 7. 示例 JSP
|
务必注意,jsp 文件的主体中引用的 jpg 文件和 zip 文件的名称和位置必须与您在本练习的第一步中部署这些文件时使用的名称和位置匹配。
AttachmentClient 项目现在已完成。此项目的内容应与图 23 中所示相同:
图 23. 最终的项目
|
使用生成的客户机测试服务
在此部分,我们将测试服务并查看输出。启动测试
- 为了确保服务器已准备好进行测试,最好重新构建工作区。为此,请选择 Project => Clean,然后选择 Clean all projects 并单击 OK。
- 应再次将更改部署到服务器。转到 Servers 选项卡,右键单击 WebSphere server 并单击 Publish。
- 要启动测试,请右键单击 AttachmentClient 项目中的 AttachmentIBMTest.jsp 文件,并选择 Run=>Run on Server。
- 在 Select a Server 对话框中,选择 WebSphere server 并单击 Finish,如图 24 中所示:
图 24. Server Selection 页
这将打开一个浏览器,您可以在浏览器中看到来自 JSP 的输出。由于 JSP 文件在显示输出前会调用 AttachmentIBMProxy,测试的结果应该在浏览器显示 JSP 的输出后很快在 Console 选项卡中显示测试的结果。也就是说,不必在浏览器中进行任何单击操作来完成测试。
查看输出
请单击 Console 选项卡,以查看测试的输出,如图 25 中所示:
图 25. 测试输出
输出表明,处理程序检查了 SOAP 消息,发现了我们的三个附件,并输出了每个附件的 mine 类型。您将看到 Web 服务的输出显示了两个字符串(一个来自消息主体,一个来自附件)、一些图像属性以及表明存在 zip 附件的信息。(本文不讨论如何使用包含 zip 文件的 DataHandler。)
|
总结
在本文中,我们说明了一项用于创建能接收包含附件(除消息主体中的正常内容外)的 SOAP 消息的 Web 服务的技术。在这个简单的示例中,服务会接收主体中的文本消息以及作为附件的文本消息、jpeg 文件和 zip 文件。我们随后在测试服务器上运行了该应用程序,并对其输出进行了观察。
|
下载
描述 | 名字 | 大小 | 下载方法 |
---|---|---|---|
Sample code for this article | AttachmentsFiles.zip | 8KB | FTP|HTTP |
文章来源于领测软件测试网 https://www.ltesting.net/
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073