本文共 9514 字,大约阅读时间需要 31 分钟。
Web 服务使用 Simple Object Access Protocol (SOAP) 通过 HTTP 传递消息。一个 SOAP 消息是一个遵循特定格式的 XML 文档:信封、头、正文和附件。由于 SOAP 消息格式包括显式附件字段,在本文中,我们将 SOAP 附件看作 “物理附件”,与前面描述的 “逻辑附件” 形成对比。在本节中,我们使用 来展示如何应用 Claim Check 模式来处理 SOAP 附件。
我们的示例需要我们创建一个带附件的 SOAP 消息。这可以使用 Integration Developer 测试客户端简单完成,它支持发送一个带附件的 SOAP 消息来调用一个 Web 服务。在 Integration Developer 中,调用一个 Web 服务实际上意味着调用一个导出上的 Web 服务绑定。我们在后面将详细解释如何使用 Integration Developer 测试客户端。首先,我们重点介绍使用 Integration Developer 和 Process Server V6.2.0.1 处理 SOAP 附件的 Claim Check 模式解决方案的关键方面。两个主要方面是:
签入和签出 SOAP 附件实际上是对 SOAP 消息的操作。Process Server 提供 Service Message Object (SMO) APIs,允许用户操作 SOAP 附件。在 中,我们使用两个中介组件中的这些 APIs,这两个中介组件是 OrderToShipment 模块中的 ProcessIncomingAttachment 和 ProcessOutgoingAttachment。图 25 显示了 OrderToShipment 模块组装图中的两个中介组件。
ProcessIncomingAttachment 组件负责将一个 SOAP 附件存储到 Claim Check 数据存储中,方式是使用 checkInAttachment 包含以下 Java 片段(清单 6)的自定义中介原语。
//Get SOAP attachment contentsAttachmentType attachment = (AttachmentType)smo.getAttachments().get(0);System.out.println("Detaching the attachment and checking it in using the ClaimCheck service as a byte array: " + attachment.getData());//Locate a BO factory service to create the input data object.BOFactory boFactory = (BOFactory)ServiceManager.INSTANCE. locateService("com/ibm/websphere/bo/BOFactory");//Now we create a new instance of the ClaimCheck service input data object.DataObject claimCheckDataobject = boFactory. create("http://CommonLibrary", "ClaimCheckObject");//Attachment is passed in as a byte array so we need to use the method //setBytes to set the data.claimCheckDataobject.setBytes("data", attachment.getData());ClaimCheckInvoker invoker = new ClaimCheckInvoker("ClaimCheckIntfPartner");//Invoke checkin method passing the default store as Flat File to store //the data on the file systemDataObject returnValue = invoker.checkIn(claimCheckDataobject, "FF");//extract the file name from the returned object and then store this //name as a text string.DataObject returnToken = ((DataObject)returnValue). getDataObject("token");String fileName = returnToken.getString("claimtoken");//Attaching the file name of the file containing the attachment //content as an attachmnet to the SMOSystem.out.println("Attaching the file name containing the attachment contents to the SMO: " + fileName);attachment.setData(((String)fileName).getBytes()); out.fire(smo); // propagate the service message object to the primitive that is //wired to the 'out' terminal |
注意,Claim Check 服务返回的索取令牌存储在 SOAP 附件之前所在的同一位置,因此稍后可使用该令牌获取 SOAP 附件。
由于 SOAP 附件的签入,从 ProcessIncomingAttachment 组件传出的消息是一个轻量级消息,可由另一个组件(比如我们样例应用程序中的 CreateWSShipment 组件)内的业务逻辑轻松使用。不过,除了执行业务功能之外,CreateWSShipment 组件需要做的一件很重要的事是将索取令牌(附件文件名)从传入的消息移到传出的消息中(图 26)。不这样做会阻止下游组件使用索取令牌来获取 SOAP 附件。
完成业务逻辑之后,如果必要,需要签出 SOAP 附件并将其重新附着到 SOAP 消息中。在我们的样例应用程序中,我们假定需要签出 SOAP 附件,且 ProcessOutgoingAttachment 组件(参见 )负责使用名为 CheckOutAttachment (清单 7)的一个自定义中介原语签出附件。
AttachmentType attachment = (AttachmentType)smo.getAttachments().get(0);//Get the file name from the attachment. This file name will be used to //check the attachment contents out from the ClaimCheck servicebyte[] fileNameBytes = attachment.getData();String fileName = new String(fileNameBytes);System.out.println("Using the ClaimCheck file name from the attachment to check the real attachment from the ClaimCheck store: " + fileName);//In this case the ticket passed to this method is a byte array. //So we need to construct the data object to invoke the service. BOFactory boFactory = (BOFactory)ServiceManager.INSTANCE. locateService("com/ibm/websphere/bo/BOFactory");//Creating a new input data object.DataObject ticketBO = boFactory. create("http://CommonLibrary", "TicketEnvelope");//The ticket is the text representing the file name. So we can use this //parameter to set the attribute on the input data object for the //checkout operation.ticketBO.set("claimtoken", fileName);//The sample application uses the Flat file adapter to store the object on //the file system.ticketBO.set("storetype", "FF");//Checking the attachment outClaimCheckInvoker invoker = new ClaimCheckInvoker("ClaimCheckIntfPartner");//We need to pass the boolean TRUE if we want to clean up the file //system from the checked in object.//If we want to keep the file on the file system, then the boolean //FALSE needs to be passed to the checkOut method.DataObject checkedOut = invoker.checkOut(ticketBO, true);//Get the attachment in the byte array format from the data object //returned by the service. byte[] checkedOutAttachmentData = checkedOut.getBytes("data"); //Setting the real attachment data back on the SMO.System.out.println("Setting the checked out real attachment data back on the SMO: " + checkedOutAttachmentData.toString());attachment.setData(checkedOutAttachmentData); out.fire(smo); //Propagate the service message object to the primitive //that is wired to the 'out' terminal. |
当消息从 ProcessOutgoingAttachment 组件传出时,它包含 SOAP 附件数据,且可被传递给 ShipmentProcessing 模块。
ShipmentProcessing 模块内的处理在本文前面已有介绍。基本上,它的工作就是将其输入数据对象的内容(特别是附件)写出到系统输出上。图 27 显示,ShipmentProcessing 模块有一个 Web 服务导出,使其能由 ProcessOutgoingAttachment 中介组件调用。
为让 ShipmentProcessing 模块写出其输入数据对象中的附件内容,对逻辑附件使用 ProcessShipmentComponentStub Java 片段。但是,同样的 Java 片段不适用于通过 ShippingWSExport 传入的物理附件。因此,如图 27 所示插入 CheckAttachment 中介组件,以写出物理附件内容。
注意,您需要一个 WebSphere Process Server V6.2.0.1 或更高版本的测试环境来运行这部分样例应用程序。运行和测试样例应用程序最简单的方式是,使用 Process Server 测试环境,该环境可随 Integration Developer 安装。在运行和测试样例应用程序之前,您必须首先部署应用程序。
部署:
要测试使用逻辑附件的样例应用程序:
注意,在 “Initial request parameters” 表中有两个高级节点(图 32)。一个节点用于 OrderIn 消息,而另一个用于 productItemIn 消息。这两个消息需要用到,且 AddLogicalAttachmentToOrder 中介组件采用 productItemIn 并使其成为 inputOrder 消息的一个逻辑附件。AddLogicalAttachmentToOrder 也将其他相关字段从 OrderIn 复制到 inputOrder。
当样例应用程序完成处理时,您可以看到来自客户端的所有跟踪栈和消息。
如图 34 所示,左边高亮显示的栏是调用 checkin 服务之前的调用。在右边,高亮显示的字段是逻辑附件的内容。
图 35 显示调用 checkin 服务之后的结果。如图 35 所示,productItem 被更改为包含存储附件内容和存储类型的文件名。如果您想看到文件系统中的附件内容,就需要使用 ClaimCheckInvoker.checkOut(ticketBO, false),将代码更改为在 checkout 服务之后不调用 cleanup 服务。当您再次重新运行应用程序时,可以转至 C:\FlatFilesAny,打开 ClaimCheckObject.xx.txt 来检查内容。
图 36 显示了调用 checkout 服务之前的信息,且产品说明仍然是高亮显示的文件名。
在调用 checkout 之后,Integration Test 客户端不显示进一步信息。不过,从 Server Logs 视图上,您可以看到 “Order shipped” 消息(图 37)。记得之前 “Order shipped” 消息由 ShipmentProcessing 模块中的 ProcessShipmentComponentStub 组件写到了日志文件中。
双击日志消息 <?xml version=”1.0” encoding=”UTF-8”?>,它就在 Server Logs 视图中的 “Order shipped” 消息下面。一个如图 38 所示的 Properties 对话框显示。对话框显示提供给 ShipmentProcessing 模块的数据。Properties 对话框中显示的实际数据反映您之前输入的初始请求参数。
要测试使用 SOAP 附件的样例应用程序,您需要完成以下几个步骤:
要开始测试:
您可以使用 Integration Test Client 捕获的细粒度跟踪验证测试结果。注意,Integration Test Client 仅显示值编辑器中的业务对象。它不 显示二进制附件。不过,我们可以在 ClaimCheckerInvoker 服务前后检查消息来验证结果。
如图 47 所示,在调用 checkin 服务之前,附件包含右边高亮显示的那些二进制附件。
图 48 显示调用 checkin 服务的结果。附件仅是一个轻量级文件名。如果您想查看文件系统中的附件内容,就需要使用 ClaimCheckInvoker.checkOut(ticketBO, false),将代码更改为在 checkout 服务之后不调用 cleanup 服务。当您再次重新运行应用程序时,可以转至 C:\FlatFilesAny,打开 ClaimCheckObject.xx.txt 来检查内容。
您可以看到,附件内容仍然是调用 checkout 服务之前的文件名,如图 49 所示。
图 50 显示,在调用 checkout 服务之后,附件内容成为原始附件数据。
本文描述了 Claim Check 模式,包括逻辑和物理 SOAP 附件。向您展示了作为 SCA 服务实现的 Claim Check 服务的样例设计和实现、一个客户端应用程序设计样例,以及通过 HTTP 和 Web Service SOAP 通信渠道使用 XML 的两个场景。您学习了如何使用自定义数据处理程序或自定义中介调用 Claim Check 服务,如何使用 Flat File 适配器存储和读取文件系统上附件的内容。
我们对样例应用程序进行了一些简化,重点介绍本文的主题:Claim Check 模式设计和实现。如果您有任何问题或您的某个用例需要建议,请随时联系作者。
原文链接:
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14789789/viewspace-673752/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/14789789/viewspace-673752/