翻译|其它|编辑:郝浩|2008-01-14 11:25:41.000|阅读 1362 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
本文首先将提供一些关于 SOAP Header 及不同类型 SOAP Header 的背景信息。然后将说明 SOAP Header 如何在 IBM? WebSphere? Enterprise Service Bus 中作为服务消息对象(Service Message Object,SMO)的一部分进行表示。介绍了一些您需要了解的基础中介模块概念后,文章最后将介绍如何使用 WebSphere Enterprise Service Bus 中提供的中介基元对 SOAP Header 进行操作,以及如何使用 SOAP Header 的内容来进行路由决策和充实服务请求。
基础
本文假定您具有 WebSphere Integration Developer、WebSphere Enterprise Service Bus 或 WebSphere Process Server V6.0.2 的基本知识。另外,对 Web 服务和 SOAP 之类的概念有基本的了解也会有所帮助,当并不是必须的。
什么是 SOAP Header?
SOAP 规范将 SOAP Header 定义为“一种扩展机制,用于提供在 SOAP 消息中传递应用程序有效负载之外的信息的方法”。大家所熟知的 WS-Security之类的 Header 传递关于消息的控制信息,但还可以使用自定义 Header 来传递其他非业务信息。这里的关键点在于,不应在 SOAP Header 中传递业务信息,而应将其放入消息主体(或有效负载)中。
隐式或显式?
SOAP Header 可以为隐式或显式的:
无论使用隐式还是显式 SOAP Header,其在 WebSphere Enterprise Service Bus 内的表示形式都是一样的。不过,如果使用隐式 SOAP Header,则需要通过业务对象定义的方式向 WebSphere Enterprise Service Bus 提供 Header 结构的定义。(本文稍后将对此进行更为详细的说明。)
中介模块
中介模块 是组合服务应用程序的部署单元,需要能够访问 WebSphere Enterprise Service Bus 和 WebSphere Process Server 的特定传输 Header。相反,业务模块 用于不需要访问传输 Header 的服务应用程序。
图 1 显示了一个典型的中介模块(使用 WebSphere Integration Developer 内的工具开发)。
图 1. 中介模块
其组成部分包括:
导入、导出和组件都有定义服务请求、响应和错误的结构的接口。导入和导出都具有一个确定使用哪个传输特定的通信协议的绑定——例如,Web 服务、IBM WebSphere MQ、Java? Message Service (JMS)、WebSphere MQ JMS 或服务组件体系结构(Service Component Architecture,SCA)。
服务消息对象
在中介模块中(以及业务模块中),所有服务数据都表示为服务数据对象(Service Data Object,SDO),从而提供了用于访问数据的通用方法,而不受所使用的传输的影响。不过,在中介流组件内,名为服务消息对象(Service Message Object,SMO)的专用 SDO 提供用户友好的数据(包括传输特定的 Header)表示形式。清单 1 显示了基本的 SMO 结构。
清单 1. 服务消息对象结构
<smo:smo xmlns:smo="http://www.ibm.com/websphere/sibx/smo/V6.0.1"> <context> <correlation> Used to store information for use in a service response </correlation> <transient> Used to store information for use later in same service request </transient> <failInfo> Used to store failure information when something goes wrong </failInfo> <primitiveContext> Used to store information specific to a mediation primitive </primitiveContext> </context> <headers> <SMOHeader> Information relating to the SMO itself </SMOHeader> <JMSHeader> JMS header information appears here </JMSHeader> <SOAPHeader> SOAP header information appears here </SOAPHeader> <SOAPFaultInfo> SOAP fault information appears here </SOAPFaultInfo> <properties> Custom user properties can appear here </properties> <MQHeader> MQ header information appears here </MQHeader> </headers> <body> The payload of your service request will be here </body> </smo:smo> |
本文剩下的部分专门讨论 SMO 的 SOAPHeader
部分。
SOAP Header 和 SMO
解释如何在 SMO 中表示 SOA Header 的最好方法是通过几个示例进行说明。首先,以包含单个 SOAP Header(一个字符串)的传入 SOAP 消息为例。清单 2 包含这样的 Header 的一个示例,名为 CustomerRating
。
清单 2. 示例 SOAP 消息
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://www.w3.org/2001/12/soap-envelope" xmlns:q0="http://ServiceLibrary/CustomerService" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Header> <MyPrefix:CustomerRating xmlns:MyPrefix="http://SOAPHeaderDemonstration"> Premium </MyPrefix:CustomerRating> </SOAP-ENV:Header> <SOAP-ENV:Body> <q0:create> <customer> <id>ABCDE12345</id> <name>John Smith</name> <address> <number>1</number> <street>The Street</street> <town>The Town</town> <postcode>AB1 2CD</postcode> </address> </customer> </q0:create> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
此信息进入中介流组件后,将会表示为清单 3 中所示的 SMO。
清单 3. 传入 SOAP 消息的服务消息对象表示形式
<?xml version="1.0" encoding="UTF-8"?> <smo:smo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:smo="http://www.ibm.com/websphere/sibx/smo/v6.0.1" xmlns:customerService="http://ServiceLibrary/CustomerService" xmlns:demoSoapHeader="http://SOAPHeaderDemonstration"> <context/> <headers> <SMOHeader> <MessageUUID>78B318CA-0114-4000-E000-1E3C09910DD5</MessageUUID> <Version> <Version>6</Version> <Release>0</Release> <Modification>2</Modification> </Version> <MessageType>Request</MessageType> </SMOHeader> <SOAPHeader> <nameSpace>http://SOAPHeaderDemonstration</nameSpace> <name>CustomerRating</name> <value xsi:type="demoSoapHeader:CustomerRating"> Premium </value> </SOAPHeader> </headers> <body xsi:type="customerService:createRequestMsg"> <create> <customer> <id>ABCDE12345</id> <name>John Smith</name> <address> <number>1</number> <street>The Street</street> <town>The Town</town> <postcode>AB1 2CD</postcode> </address> </customer> </create> </body> </smo:smo> |
请注意传入 SOAP Header 元素的命名空间、名称和值已经复制到了 SMO 中相应的位置。请注意,未复制 SOAP Header 的前缀,因为这没有业务意义,只是指向 SOAP Header 命名空间的指针。
现在以包含更多结构且更为有用的 SOAP Header 为例。在此例中,传入 SOAP 消息具有一个 SOAP Header,是复杂类型 CallingApplication
,此类型包括三个子元素。
清单 4. CallingApplication 的 SOAP Header
<SOAP-ENV:Header><MyPrefix:CallingApplication xmlns:MyPrefix="http://SOAPHeaderDemonstration"> <name>ServiceRequester1</name> <version>1.0</version> <timeRequestMade>13:20:00</timeRequestMade> </MyPrefix:CallingApplication> </SOAP-ENV:Header> |
CallingApplication
Header 在 SMO 中表示为清单 5 中所示的代码。
清单 5. 表示 CallingApplication Header 的服务消息对象
<SOAPHeader> <nameSpace>http://SOAPHeaderDemonstration</nameSpace> <name>CallingApplication</name> <value xsi:type="applicationHeader:CallingApplicationType"> <name>ServiceRequester1</name> <version>1.0</version> <timeRequestMade>13:20:00</timeRequestMade> </value> </SOAPHeader> |
建模隐式 SOAP Header
无论所涉及的 SOAP Header 类型如何,WebSphere Enterprise Service Bus(或 WebSphere Process Server)都需要知道传入 SOAP Header 的结构。如果 Header 是显式的(即在 WSDL 中定义),则这样就足够了。不过,如果 Header 是隐式的,这就意味着需要在中介模块中以业务对象的形式定义 Header 的结构。假如您要将上面两个示例建模为隐式 Header;对于简单类型 Header,其在业务对象编辑器中建模的情况如图 2 中所示。
图 2. CustomerRating 业务对象
请看 CustomerRating
业务对象的定义,其 XML 模式如清单 6 中所示。
清单 6. CustomerRating XSD
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://SOAPHeaderDemonstration"> <xsd:simpleType name="CustomerRating"> <xsd:restriction base="xsd:string"/> </xsd:simpleType> </xsd:schema> |
在第二示例(复杂类型)中,此 Header 在业务对象编辑器中建模的情况如图 3 中所示。
图 3. CallingApplication 业务对象
CallingApplication
业务对象与清单 7 中的 XML 模式对应;此模式定义了引用复杂类型的全局元素。
清单 7. CallingApplication XSD
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://SOAPHeaderDemonstration" targetNamespace="http://SOAPHeaderDemonstration"> <xsd:element name="CallingApplication" type="tns:CallingApplicationType" /> <xsd:complexType name="CallingApplicationType"> <xsd:sequence> <xsd:element minOccurs="0" name="name" type="xsd:string"/> <xsd:element minOccurs="0" name="version" type="xsd:double"/> <xsd:element minOccurs="0" name="timeRequestMade" type="xsd:time"/> </xsd:sequence> </xsd:complexType> </xsd:schema> |
在后面部分中,让我们假定传入 SOAP 消息 Header 包含这两个 SOAP Header,因此对应的 SMO 表示形式如清单 8 中所示。
清单 8. 传入 SOAP 消息的服务消息对象表示形式
<?xml version="1.0" encoding="UTF-8"?> <smo:smo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:smo="http://www.ibm.com/websphere/sibx/smo/v6.0.1" xmlns:customerService="http://ServiceLibrary/CustomerService" xmlns:demoSoapHeader="http://SOAPHeaderDemonstration> <context/> <headers> <SMOHeader> <MessageUUID> 6A5AC8E1-0114-4000-E000-34787F000001 </MessageUUID> <Version> <Version>6</Version> <Release>0</Release> <Modification>2</Modification> </Version> <MessageType>Request</MessageType> </SMOHeader> <SOAPHeader> <nameSpace>http://SOAPHeaderDemonstration</nameSpace> <name>CallingApplication</name> <value xsi:type="demoSoapHeader:CallingApplication"> <name>ServiceRequester1</name> <version>1.0</version> <timeRequestMade>13:20:00</timeRequestMade> </value> </SOAPHeader> <SOAPHeader> <nameSpace>http://SOAPHeaderDemonstration</nameSpace> <name>CustomerRating</name> <value xsi:type="demoSoapHeader:CustomerRating"> Premium </value> </SOAPHeader> </headers> <body xsi:type="customerService:createRequestMsg"> <create> <customer> <id>1234</id> <name>Joe Blogs</name> <address> <number>1</number> <street>The Street</street> <town>The Town</town> <postcode>AB1 2CD</postcode> </address> </customer> </create> </body> </smo:smo> |
在中介基元中引用 SOAP Header
在中介流内,中介基元 用于操作 SMO 和提供企业服务总线通常预期的功能,如路由、转换、充实和日志记录。每个中介基元都有一组属性,能够对其进行配置以执行所需的中介逻辑。XPath 表达式用于在 SMO 中引用位置。通过使用上面的示例 SMO,清单 9 显示了引用 CallingApplication
SOAP Header 的值中的 version 元素的一些示例 Xpath 表达式。
清单 9. 示例 XPath 表达式
/headers/SOAPHeader[name="CallingApplication" and nameSpace="http://SOAPHeaderDemonstration"]/value/version //SOAPHeader[name="CallingApplication" and nameSpace="http://SOAPHeaderDemonstration"]//version //SOAPHeader[1]/value/version |
清单 9 所示的第一个示例表达式是引用 version 元素最具体的方式,也是最好的方式。但其他 XPath 表达式也同样有效。
请注意:XPath 使用 1-n 基础数组,因此 SOAPHeader
数组使用索引 1(而不是 0)进行限制。
要引用 CustomerRating
SOAP Header 的实际文本值,XPath 将为 /headers/SOAPHeader[name="CustomerRating" and namespace="http://SOAPHeaderDemonstration"]/value/value
,因为 SDO 表示名为 value 的属性中包含的简单类型。
现在您已经了解了中介基元如何引用 SOAP Header 中的数据,接下来我们将了解如何使用提供的中介基元执行最为常见的任务。
修改现有 SOAP Header
访问了中介流中的 SOAP Header 后,可能需要采用某种方式对其进行修改。可以使用多个基元进行此工作,选择使用哪个基元通常取决于操作的复杂性。选择要使用哪个基元很大程度上取决于您自己,不过,通过使用 Message Element Setter,可以显示单个消息元素的 value 属性,并在应用程序部署之后通过管理控制台对其进行更改。如果希望执行复杂操作来形成数据,XSL Transformation (XSLT) 可能是最好的选择。
使用 Message Element Setter 修改 CallingApplication SOAP Header 的命名空间
要使用 Message Element Setter 修改 SOAP Header,可以将图 4 中所示的图标添加到中介流中,并配置其属性,如图 5 中所示。
图 4. Message Element Setter 中介基元
图 5. Message Element Setter 的属性编辑器
target 属性引用 SMO 中要修改的元素,在此示例中使用的是 XPath 表达式 /headers/SOAPHeader[name='CallingApplication']/namespace
。type 属性引用所修改的元素类型,在本例中使用的是 String。最后,value 属性为要使用的值。
使用 XSLT 来修改 CustomerRating SOAP Header 的值
图 6. XSLT 中介基元
要使用 XSLT 中介基元,请将图 6 中的图标添加到中介流,并按以下所述配置其属性:在 Properties 面板的 Details 选项卡中,可以将其与现有 XSL 样式表关联,或使用映射编辑器来从头创建新的样式表。
此示例说明如何将所有 SOAP Header 映射到目标消息,但要将命名空间 http://SOAPHeaderDemonstration
更改为 http://myNewNamespaceValue
。
然后将自动打开映射编辑器(请参见图 8)。target 是所创建的消息,可以映射来自源消息的值,也可以指定固定值。
如果右键单击选择的元素,会给出一系列选项。在此示例中,您要进行以下操作:
SMOHeader
下的所有元素映射到输出消息,这样可确保创建有效的目标 SMO。接下来,对除命名空间为 http://SOAPHeaderDemonstration
的任何元素之外的所有 SOAPHeaders
元素进行映射。
nameSpace
元素,请在 target 映射区域中单击鼠标右键,并选择 XSL Choose,以打开图 9 中所示的对话框。 如图 9 中所示,如果 nameSpace
元素为 http://SOAPHeaderDemonstration
,则将更改为 http://myNewNamespaceValue
。XSL 还包含一个 otherwise 子句,此子句会在命名空间不为 http://SOAPHeaderDemonstration
时映射到原始值。
使用数据库查询修改 CustomerRating SOAP Header 的内容
图 10. Database lookup 中介基元
Database lookup 中介基元类似于 Message Element Setter 基元,因为可以将其用于对现有消息进行充实。区别在于,它会从数据库中包含的信息获取值。要使用 Database lookup 中介基元,请将图 10 中的图标添加中介流,并按照以下所述配置其属性(如图 11 中所示):Data source name 和 Table name 属性指定使用哪个数据库和表。Key path 属性是要将其值作为数据库中的查询键使用的消息的位置。如果找到了匹配项,将提取 Data elements 表属性中指定的信息,并用于修改传入消息。
图 11. Database lookup 属性
在图 11 所示的示例中,消息中的 customerID
值在数据库中,CustomerType
列的值在元素 /headers/SOAPHeader/[name=’CustomerRating’]/value/value
中设置。
创建新的 SOAP Header
如果需要调用包括尚未包含在传入请求中(因为不需要,或者导出绑定不是 Web 服务)的 SOA Header 的 Web 服务导入,请使用提供的基元将新 SOAP Header 添加到 SMO 中。可以通过多种方式实现此目标,包括使用自定义中介或 XSLT 中介基元。
图 12 和清单 10 说明了如何创建名为 CallerInformation
的新 SOAP Header。
图 12. CallerInformation 业务对象
清单 10 中给出了描述 CallerInformation
Header 的 XSD。
清单 10. CallerInformation XSD
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://CustomerService"> <xsd:complexType name="CallerInformation"> <xsd:sequence> <xsd:element minOccurs="0" name="id" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema> |
使用自定义中介添加新的 SOAP Header
要使用自定义中介基元,请将图 13 中所示的图标添加到中介流中。
图 13. 自定义中介基元
在属性编辑器的 Java implementation 部分中添加清单 11 中的代码,以创建新的 CallerInformation
Header。
清单 11. 自定义中介 Java 脚本
import java.util.List; import commonj.sdo.DataObject; import com.ibm.websphere.bo.BOFactory; import com.ibm.websphere.sca.ServiceManager; import com.ibm.websphere.sibx.smobo.ServiceMessageObject; import com.ibm.websphere.sibx.smobo.SOAPHeaderType; import com.ibm.websphere.sibx.smobo.ServiceMessageObjectFactory; ServiceBusinessObject inputSMO = (ServiceMessageObject)input1; List soapHeaders = inputSMO.getHeaders().getSOAPHeader(); SOAPHeaderType soapHeader = ServiceMessageObjectFactory.eINSTANCE.createSOAPHeaderType(); soapHeader.setName("CallerInformation"); soapHeader.setNameSpace("http://myCallerInformationNameSpace.com"); soapHeader.setPrefix("shp"); BOFactory boFactory = (BOFactory) ServiceManager.INSTANCE.locateService("com/ibm/websphere/bo/BOFactory"); DataObject soapHeaderValue = boFactory.create("http://CustomerService","CallerInformation"); soapHeaderValue.setString("value","myNewValue"); soapHeader.setValue(soapHeaderValue); soapHeaders.add(soapHeader); return input1; |
请注意:要使用 BOFactory
创建数据对象,必须定义复杂类型或全局元素。
使用 XSLT
可以通过定义 XSL 文件来创建新的 SOAP Header。清单 12 中的代码说明如何创建 CallerInformation
Header,其中的 id value
为 CallingApplication
Header 中包含的所有信息的串联值。
清单 12. 用于创建 CallerInformation Header 的 XSL 模板
<xsl:stylesheet version="1.0" ... xmlns:tns_1="http://CustomerService" ...> <xsl:template match="SMOHeader"> <SOAPHeader> <nameSpace>http://myCallerInformationNameSpace.com</nameSpace> <name>CallerInformation</name> <prefix>ns1</prefix> <value xsi:type="tns_1:CallerInformation"> <id>xsl:value-of select="concat(/headers/SOAPHeader [name='CallingApplication']/value/name/text(), /headers/SOAPHeader [name='CallingApplication']/value/version/text(), /headers/SOAPHeader [name='CallingApplication']/value/timeRequestMade/text())"/> </id> </value> </SOAPHeader> </xsl:template> |
删除现有 SOAP Header
使用 SOAP Header 中的信息执行所需的中介逻辑之后,可能会希望将其删除,以使其不会传播到不需要此信息的导入。
使用 Message Element Setter 删除 CallingApplication SOAP Header
Message Element Setter 中介基元提供了删除服务请求中的元素的简单方法,SOAP Header 也不例外。要删除前面的 CallingApplication
SOAP Header,可以配置 Message Element Setter 属性,将目标元素的类型设置为 delete(请参见图 14)。
图 14. 使用 Message Element Setter 删除 SOAP Header
基于 SOAP Header 进行路由
您可能会希望基于 SOAP Header 的内容进行路由。例如,以前面的 CallingApplication
SOAP Header 为例,您可能希望基于 CallingApplication
的名称或版本或者请求时间路由到不同的服务。可以通过使用 Message Filter 中介基元进行此工作(请参见图 15)。
图 15. Message filter 中介基元
基于 CallingApplication SOAP Header 的 version 字段筛选服务请求
要使用 Message Filter 中介基元,请将图 15 中所示的图标放置到中介流中,并按照图 16 中所示配置其属性。
图 16. 基于 SOAP Header 内容路由消息
总结
本文首先介绍 SOAP Header 的用途和不同类型的可用 SOAP Header。然后我们介绍了其如何在 WebSphere Enterprise Service Bus 中作为 SMO 的一部分进行表示。最后,我们给出了几个示例,说明如何使用提供的中介基元添加、修改和删除 SOAP Header,以及如何基于 SOAP Header 内容进行路由决策、执行转换和充实服务请求
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:IBM