在 WebSphere Enterprise Service Bus 和 WebSphere Process Server V6.0.2 中操作 SOAP Header

翻译|其它|编辑:郝浩|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 可以为隐式或显式的:

  • 显式 Header 在用于描述服务接口的 Web 服务描述语言(Web Services Description Language,WSDL)文档中显式定义。
  • 隐式 Header 仍然包括在消息中,但没有 WSDL 定义。

无论使用隐式还是显式 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. 中介模块
中介模块

其组成部分包括:

  • ImportedService:定义如何连接到现有服务的导入
  • ExposedService:定义如何将新构造的服务应用程序向外部公开的导出
  • Mediation:用于在导出与导入之间进行连接的中介组件,其中包含中介逻辑

导入、导出和组件都有定义服务请求、响应和错误的结构的接口。导入和导出都具有一个确定使用哪个传输特定的通信协议的绑定——例如,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 业务对象

请看 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 业务对象

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 中介基元
Message Element Setter 中介基元

图 5. Message Element Setter 的属性编辑器
Message Element Setter 的属性编辑器

target 属性引用 SMO 中要修改的元素,在此示例中使用的是 XPath 表达式 /headers/SOAPHeader[name='CallingApplication']/namespacetype 属性引用所修改的元素类型,在本例中使用的是 String。最后,value 属性为要使用的值。

使用 XSLT 来修改 CustomerRating SOAP Header 的值


图 6. XSLT 中介基元
XSLT 中介基元

要使用 XSLT 中介基元,请将图 6 中的图标添加到中介流,并按以下所述配置其属性:在 Properties 面板的 Details 选项卡中,可以将其与现有 XSL 样式表关联,或使用映射编辑器来从头创建新的样式表。

此示例说明如何将所有 SOAP Header 映射到目标消息,但要将命名空间 http://SOAPHeaderDemonstration 更改为 http://myNewNamespaceValue

  1. 创建新的映射,并在提示时(请参见图 7)指定 Message Root(即从其应用转换的位置)、Input Message Body 类型和 Output Message Body 类型(如果已经对中介流进行了连接,则这些字段已完成)。
  2. 指定 Message Root 时,您需要考虑需要在映射中访问消息的哪些部分。选择 / 可获得对 SMO 的完全访问权限,而如果仅需要访问 SMO 的 headers 部分,则选择 /headers

    图 7. 创建新的 XSLT 映射
    创建新的 XSLT 映射

    然后将自动打开映射编辑器(请参见图 8)。target 是所创建的消息,可以映射来自源消息的值,也可以指定固定值。



    图 8. XSLT 映射编辑器
    XSLT 映射编辑器

    如果右键单击选择的元素,会给出一系列选项。在此示例中,您要进行以下操作:

  3. 在 source 中选择 SMOHeader 元素,然后在 target 中右键单击相同的元素,然后选择 Match Mapping。这会将源消息的 SMOHeader 下的所有元素映射到输出消息,这样可确保创建有效的目标 SMO。

接下来,对除命名空间为 http://SOAPHeaderDemonstration 的任何元素之外的所有 SOAPHeaders 元素进行映射。

  1. 在 target 和 source 中选择 SOAPHeaders 元素,并执行 Create Mapping 功能。
  2. 对 SOAPHeader 下的 name、prefix 和 value 元素重复此过程。请注意,编辑器会在已经映射的元素旁边显示箭头图标。
  3. 对于 nameSpace 元素,请在 target 映射区域中单击鼠标右键,并选择 XSL Choose,以打开图 9 中所示的对话框。

    图 9. 在 XSLT 中创建选择
    在 XSLT 中创建选择

如图 9 中所示,如果 nameSpace 元素为 http://SOAPHeaderDemonstration,则将更改为 http://myNewNamespaceValue。XSL 还包含一个 otherwise 子句,此子句会在命名空间不为 http://SOAPHeaderDemonstration 时映射到原始值。

使用数据库查询修改 CustomerRating SOAP Header 的内容


图 10. Database lookup 中介基元
Database lookup 中介基元

Database lookup 中介基元类似于 Message Element Setter 基元,因为可以将其用于对现有消息进行充实。区别在于,它会从数据库中包含的信息获取值。要使用 Database lookup 中介基元,请将图 10 中的图标添加中介流,并按照以下所述配置其属性(如图 11 中所示):Data source name 和 Table name 属性指定使用哪个数据库和表。Key path 属性是要将其值作为数据库中的查询键使用的消息的位置。如果找到了匹配项,将提取 Data elements 表属性中指定的信息,并用于修改传入消息。


图 11. Database lookup 属性
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 业务对象
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 valueCallingApplication 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
使用 Message Element Setter 删除 SOAP Header

基于 SOAP Header 进行路由

您可能会希望基于 SOAP Header 的内容进行路由。例如,以前面的 CallingApplication SOAP Header 为例,您可能希望基于 CallingApplication 的名称或版本或者请求时间路由到不同的服务。可以通过使用 Message Filter 中介基元进行此工作(请参见图 15)。


图 15. Message filter 中介基元
Message filter 中介基元

基于 CallingApplication SOAP Header 的 version 字段筛选服务请求

要使用 Message Filter 中介基元,请将图 15 中所示的图标放置到中介流中,并按照图 16 中所示配置其属性。


图 16. 基于 SOAP Header 内容路由消息
基于 SOAP Header 内容路由消息 

总结

本文首先介绍 SOAP Header 的用途和不同类型的可用 SOAP Header。然后我们介绍了其如何在 WebSphere Enterprise Service Bus 中作为 SMO 的一部分进行表示。最后,我们给出了几个示例,说明如何使用提供的中介基元添加、修改和删除 SOAP Header,以及如何基于 SOAP Header 内容进行路由决策、执行转换和充实服务请求


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:IBM

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP