posts - 495,comments - 227,trackbacks - 0

创建 WSDL 文档

Christine 负责实际的数据,而 Larry 负责在服务及其客户机间传递的实际消息。为了处理这些消息,他创建了 WSDL 文档。

消息

Larry 的第一步是决定服务将实际执行的函数,然后再为服务定义消息。与部门的其他人商议后,他制订了函数及其对应消息的列表,我们将在这一部分的其余内容中讨论这些函数。

createNewAd

此函数在广告结束日期接受广告的内容,并返回新创建的广告的内容(请参见清单 10 和清单 11)。


清单 10. createNewAdRequest(输入)
                    
<env:Envelope 
       xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Body>
  <req:createNewAdRequest 
              xmlns:req="http://daily-moon.com/classifieds/">
     <req:content>Vintage 1963 T-Bird...</req:content>
     <req:endDate>4/30/07</req:endDate>
  </req:createNewAdRequest>
 </env:Body>


清单 11. createNewAdResponse(输出)
                    
<env:Envelope 
       xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Body>
  <res:createNewAdResponse 
              xmlns:res="http://daily-moon.com/classifieds/">
      <res:newAdId>1138</res:newAdId>
  </res:createNewAdResponse>
 </env:Body>

editExistingAd

此函数接受现有广告,并替换其在数据库中的内容。它将返回一个 Boolean 值声明,指示操作是否成功(请参见清单 12 和清单 13)。


清单 12. editExistingAdRequest(输入)
                    
<env:Envelope 
       xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Body>
  <req:editExistingAdRequest
              xmlns:req="http://daily-moon.com/classifieds/">
      <req:ClassifiedAd>
         <req:id>1138</req:id>
         <req:content>Vintage 1963 T-Bird...</req:content>
         <req:startDate>4/1/2007</req:startDate>
         <req:endDate>4/30/2007</req:endDate>
      <req:ClassifiedAd>
  </req:editExistingAdRequest >
 </env:Body>


清单 13. editExistingAdResponse(输出)
                    
<env:Envelope 
       xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Body>
  <res:editExistingAdResponse
              xmlns:res="http://daily-moon.com/classifieds/">
      <res:isOK>true</res:isOK>
  </res:editExistingAdResponse>
 </env:Body>

getExistingAds

此函数将返回现有 ClassifiedAds 的列表(请参见清单 14 和清单 15)。


清单 14. getExistingAdsRequest(输入)
                     
<env:Envelope 
       xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Body>
  <req:getExistingAdsRequest 
                  xmlns:req="http://daily-moon.com/classifieds/">
  </req:getExistingAdsRequest>
 </env:Body>


清单 15. getExistingAdsResponse(输出)
                    
<env:Envelope 
       xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Body>
  <res:getExistingAdsResponse
              xmlns:res="http://daily-moon.com/classifieds/">
    <res:ClassifiedList>
      <res:ClassifiedAd>
         <res:id>1138</res:id>
         <res:content>Vintage 1963 T-Bird...</res:content>
         <res:startDate>4/1/2007</res:startDate>
         <res:endDate>4/30/2007</res:endDate>
      </res:ClassifiedAd>
      <res:ClassifiedAd>
         <res:id>2883</res:id>
         <res:content>Championship playoff
 tickets...</res:content>
         <res:startDate>4/1/2007</res:startDate>
         <res:endDate>4/30/2007</res:endDate>
      </res:ClassifiedAd>
    </res:ClassifiedList>
  </res:getExistingAdsResponse >
</env:Body>

finalizeIssue

此函数是“仅输入”的函数,接收最终的发布日期,而并不返回任何数据(请参见清单 16)。


清单 16. finalizeIssueRequest(输入)
                    
<env:Envelope 
       xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <env:Body>
  <req:finalizeIssueRequest 
                  xmlns:req="http://daily-moon.com/classifieds/">
     <req:issueDate>4/10/06</req:issueDate>
  </req:FinalizeIssueRequest >
 </env:Body>

有了这些消息后,Larry 开始着手创建实际的 WSDL 文档。





回页首


创建基本文档

Larry 首先创建 WSDL 文档的基本框架(请参见清单 17)。


清单 17. 基本 WSDL 文档
                    
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
       targetNamespace="http://ws.apache.org/axis2">

<wsdl:types>
</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">
</wsdl:message>

<wsdl:portType name="ClassifiedServicePortType">
</wsdl:portType>

<wsdl:binding name="ClassifiedServiceBinding">
</wsdl:binding>

<wsdl:service name="ClassifiedService">
</wsdl:service>

</wsdl:definitions>

像其所定义的 SOAP 消息一样,WSDL 也是由 XML 组成的。定义位于 definitions 元素内,如此处所示。首先看下面,您定义了 serviceservice 使用一个特殊的 binding,而后者是 portType 的一个实现。portType 定义操作,而操作由 messages 组成。消息中包含由 types 部分中定义的 XML 组成。

definitions 元素定义两个命名空间。第一个使用前缀 wsdl:,为组成 WSDL 的实际元素提供命名空间。第二个 targetNamespace 定义 WSDL 定义的项所属的命名空间。

Larry 首先定义的是类型。





回页首


定义类型

Larry 拿到 Christine 提供的定义,并将其放入 types 元素中,从而在文档内创建了一个新模式,如清单 18 中所示。


清单 18. 定义类型
                    
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
       xmlns:ns1="http://org.apache.axis2/xsd" 
       targetNamespace="http://ws.apache.org/axis2">

<wsdl:types>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
         targetNamespace="http://org.apache.axis2/xsd" 
         elementFormDefault="unqualified" 
         attributeFormDefault="unqualified">

    <xs:element type="ns1:ClassifiedAd" name="ClassifiedAd" />
    <xs:complexType name="ClassifiedAd">
      <xs:sequence>
        <xs:element type="xs:int" name="id" />
        <xs:element type="xs:string" name="content" />
        <xs:element type="xs:string" name="endDate" />
        <xs:element type="xs:string" name="startDate" />
      </xs:sequence>
    </xs:complexType>

    <xs:element type="ns1:ClassifiedList" name="ClassifiedList" />
    <xs:complexType name="ClassifiedList">
      <xs:sequence>
        <xs:element minOccurs="0" type="ns1:ClassifiedAd" 
                        name="ClassifiedAd" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>

    <xs:element name="createNewAdRequest">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:string" name="content" />
          <xs:element type="xs:string" name="endDate" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

    <xs:element name="createNewAdResponse">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:int" name="newAdId" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

    <xs:element name="editExistingAdRequest">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="ns1:ClassifiedAd" 
name="ClassifiedAd" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

    <xs:element name="editExistingAdResponse">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:boolean" name="isOK" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

    <xs:element name="getExistingAdsRequest">
      <xs:complexType />
    </xs:element>

    <xs:element name="getExistingAdsResponse">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="ns1:ClassifiedList" 
                                   name="ClassifiedList" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

    <xs:element name="finalizeIssueRequest">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:string" name="issueDate" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

  </xs:schema>

</wsdl:types>

</wsdl:definitions>

从代码的起始处开始,请注意我们有两个命名空间部分。第一个位于 schema 元素本身中。此处 Larry 定义了两个命名空间。第一个命名空间是 XML Schema 命名空间,使用前缀 xs:。第二个命名空间是 targetNamespace,定义模式创建的定义所属的命名空间。也就是说,当第二个版本创建名为 ClassifiedAdcomplexType 时,该定义属于命名空间 http://org.apache.axis2/xsd。不过,为了引用该命名空间,Larry 需要创建另一个别名。您可以在以 ns1: 为前缀的 definitions 元素上看到此别名。(Larry 可以直接将该定义放在 schema 元素上,但他稍后需要在 schema 元素外使用此定义。)后面两个属性 elementFormDefaultattributeFormDefault 表示元素和属性是否应该有命名空间前缀。

前面四个定义来自 Christine 提供给 Larry 的定义,但其余定义用于定义 Larry 前面创建的消息。





回页首


有关命名空间的说明

和许多编程语言一样,在 XML 中,经常有必要为各种元素和属性指定“命名空间”。这样就能方便地对具有相同名称但用途不同(来源也可能不同)的元素进行区分。XML 通过 URI 引用命名空间。例如,XML 模式命名空间为 http://www.w3.org/2001/XMLSchema。不过,为了方便起见,还为其分配了一个别名(或前缀)。例如,此处的模式命名空间的前缀为 xs:。请记住,别名只是一个别名而已,重要的是 URI。因此,属于 ns1: 命名空间的元素或属性也是模式的 targetNamespace 的一部分。





回页首


创建消息

定义了各个类型后,Larry 就可以定义将在 SOAP 信封中来回传递的消息了(请参见清单 19)。


清单 19. 创建消息
                    
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
       xmlns:ns1="http://org.apache.axis2/xsd" 
       targetNamespace="http://ws.apache.org/axis2">

<wsdl:types>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
         targetNamespace="http://org.apache.axis2/xsd" 
         elementFormDefault="unqualified" 
         attributeFormDefault="unqualified">
...
    <xs:element name="createNewAdRequest">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:string" name="content" />
          <xs:element type="xs:string" name="endDate" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

    <xs:element name="createNewAdResponse">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:int" name="newAdId" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

...
  </xs:schema>

</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">
  <wsdl:part name="part1" element="ns1:createNewAdRequest"
 />
</wsdl:message>

<wsdl:message name="createNewAdResponseMessage">
  <wsdl:part name="part1" element="ns1:createNewAdResponse" />
</wsdl:message>

<wsdl:message name="getExistingAdsResponseMessage">
  <wsdl:part name="part1" element="ns1:getExistingAdsResponse" />
</wsdl:message>

<wsdl:message name="editExistingAdRequestMessage">
  <wsdl:part name="part1" element="ns1:editExistingAdRequest" />
</wsdl:message>

<wsdl:message name="getExistingAdsRequestMessage">
  <wsdl:part name="part1" element="ns1:getExistingAdsRequest" />
</wsdl:message>

<wsdl:message name="editExistingAdResponseMessage">
  <wsdl:part name="part1" element="ns1:editExistingAdResponse" />
</wsdl:message>

<wsdl:message name="finalizeIssueRequestMessage">
  <wsdl:part name="part1" element="ns1:finalizeIssueRequest" />
</wsdl:message>

<wsdl:portType name="ClassifiedServicePortType">
</wsdl:portType>

<wsdl:binding name="ClassifiedServiceBinding">
</wsdl:binding>

<wsdl:service name="ClassifiedService">
</wsdl:service>

</wsdl:definitions>

每个消息都具有一个 name,以便稍后对其进行引用。在每个消息内,您可以定义一个或多个 part。请注意,WSDL 2.0 仅允许每个 message 包含一个 part,因此 Larry 此处严格遵循了此约定。

每个 part 都有一个 name,而由 element 的名称组成该 part。元素名称将反过来引用在 types 元素中定义的类型。请注意,元素的名称以 ns1: 为前缀,即与模式的 targetNamespace 匹配的命名空间前缀。也就是说,当 Larry 创建 createNewAdResponse 的定义时,该定义进入了 http://org.apache.axis2/xsd namespace 中,由于前缀 ns1: 也引用此命名空间,因此现在可以使用该前缀引用此命名空间。





回页首


定义接口 (portType)

消息本身并不会带来什么好处,因此 Larry 需要将其与特定的操作关联。这些 operation 属于 portType 的一部分。portType 仅包含定义,而不包含实现。就这个意义而言,它与接口很相似。事实上,在 WSDL 2.0 中,portType 的名称已更改为 interface。Larry 为每个功能创建了一个操作(请参见清单 20)。


清单 20. 添加操作
                    
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
       xmlns:tns=http://ws.apache.org/axis2
       xmlns:ns1="http://org.apache.axis2/xsd" 
       targetNamespace="http://ws.apache.org/axis2">

<wsdl:types>
...
</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">
  <wsdl:part name="part1" element="ns1:createNewAdRequest" />
</wsdl:message>

<wsdl:message name="createNewAdResponseMessage">
  <wsdl:part name="part1" element="ns1:createNewAdResponse" />
</wsdl:message>
...
<wsdl:message name="finalizeIssueRequestMessage">
  <wsdl:part name="part1" element="ns1:finalizeIssueRequest" />
</wsdl:message>

<wsdl:portType name="ClassifiedServicePortType">

  <wsdl:operation name="finalizeIssue">
    <wsdl:input message="tns:finalizeIssueRequestMessage" />
  </wsdl:operation>

  <wsdl:operation name="createNewAd">
    <wsdl:input message="tns:createNewAdRequestMessage" />
    <wsdl:output message="tns:createNewAdResponseMessage" />
  </wsdl:operation>

  <wsdl:operation name="editExistingAd">
    <wsdl:input message="tns:editExistingAdRequestMessage" />
    <wsdl:output message="tns:editExistingAdResponseMessage" />
  </wsdl:operation>

  <wsdl:operation name="getExistingAds">
    <wsdl:input message="tns:getExistingAdsRequestMessage" />
    <wsdl:output message="tns:getExistingAdsResponseMessage" />
  </wsdl:operation>

</wsdl:portType>

<wsdl:binding name="ClassifiedServiceBinding">
</wsdl:binding>

<wsdl:service name="ClassifiedService">
</wsdl:service>

</wsdl:definitions>

Larry 创建了两种类型的消息。一类消息(如 finalizeIssue)是“仅输入”的操作,因为它仅具有输入消息。消息 finalizeIssueRequest 是前面定义的,和前面一样,我们将创建一个新前缀 tns: 来引用其所属的命名空间。

第二种操作类型是请求/响应操作,如 createNewAd。在这种情况下,Larry 将同时定义输入和输出消息。





回页首


定义绑定

如果 portType 像接口,则 binding 为该接口的实现(请参见清单 21)。


清单 21. 创建绑定
                    
<wsdl:definitions 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
       xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
       xmlns:tns="http://ws.apache.org/axis2"
       xmlns:ns1="http://org.apache.axis2/xsd" 
       targetNamespace="http://ws.apache.org/axis2">

<wsdl:types>
</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">
  <wsdl:part name="part1" element="ns1:createNewAdRequest" />
</wsdl:message>
...
<wsdl:portType name="ClassifiedServicePortType">

  <wsdl:operation name="finalizeIssue">
    <wsdl:input message="tns:finalizeIssueRequestMessage" />
  </wsdl:operation>

  <wsdl:operation name="createNewAd">
    <wsdl:input message="tns:createNewAdRequestMessage" />
    <wsdl:output message="tns:createNewAdResponseMessage" />
  </wsdl:operation>

  <wsdl:operation name="editExistingAd">
    <wsdl:input message="tns:editExistingAdRequestMessage" />
    <wsdl:output message="tns:editExistingAdResponseMessage" />
  </wsdl:operation>

  <wsdl:operation name="getExistingAds">
    <wsdl:input message="tns:getExistingAdsRequestMessage" />
    <wsdl:output message="tns:getExistingAdsResponseMessage" />
  </wsdl:operation>

</wsdl:portType>

<wsdl:binding name="ClassifiedServiceBinding" 
                         type="tns:ClassifiedServicePortType">

  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 
                                                style="document" />

  <wsdl:operation name="createNewAd">
    <soap:operation soapAction="createNewAd" style="document" />
    <wsdl:input>
      <soap:body use="literal" 
                      namespace="http://daily-moon.com/classifieds" />
    </wsdl:input>
    <wsdl:output>
      <soap:body use="literal" 
                      namespace="http://daily-moon.com/classifieds" />
    </wsdl:output>
  </wsdl:operation>

  <wsdl:operation name="finalizeIssue">
    <soap:operation soapAction="finalizeIssue" style="document" />
    <wsdl:input>
      <soap:body use="literal" 
                      namespace="http://daily-moon.com/classifieds" />
    </wsdl:input>
  </wsdl:operation>

  <wsdl:operation name="editExistingAd">
    <soap:operation soapAction="editExistingAd" style="document" />
    <wsdl:input>
      <soap:body use="literal" 
                      namespace="http://daily-moon.com/classifieds" />
    </wsdl:input>
    <wsdl:output>
      <soap:body use="literal" 
                      namespace="http://daily-moon.com/classifieds" />
    </wsdl:output>
  </wsdl:operation>

  <wsdl:operation name="getExistingAds">
    <soap:operation soapAction="getExistingAds" style="document" />
    <wsdl:input>
      <soap:body use="literal" 
                      namespace="http://daily-moon.com/classifieds" />
    </wsdl:input>
    <wsdl:output>
      <soap:body use="literal" 
                      namespace="http://daily-moon.com/classifieds" />
    </wsdl:output>
  </wsdl:operation>

</wsdl:binding>

<wsdl:service name="ClassifiedService">
</wsdl:service>

</wsdl:definitions>

首先,请注意绑定 type 引用 Larry 已经创建的 ClassifiedServicePortType。其次,请注意添加了 soap: 命名空间。此 binding 用于 HTTP 上的 SOAP 消息,如 soap:binding 元素中所示。请注意 transport 属性。(尚不用担心 style,我们将在接下来的部分中对其进行讨论。)

对于共享其在 portType 中的名称的每个操作,Larry 现在都要添加一个 soap:operation 元素。此元素执行两个操作。根据此元素的说明,第一个操作实际上是 SOAP 操作。第二个操作用于指定 soapAction,此为在实际 SOAP 消息前发送的 HTTP Header。服务器可以使用此 Header 来将请求路由到相应的操作。

请注意,soapAction 始终有一定的问题,虽然在 WSDL 1.1 是可选的,但已经完全从 WSDL 2.0 中删除了。

每个操作还定义 inputoutput 消息(或者,使用仅输入的消息时,只定义 input 消息),但现在 Larry 还将添加特定的 SOAP 信息。同样,不用担心 use 属性;我们也将在稍后讨论此属性。此元素还为有效负载的内容定义命名空间。





回页首


定义服务

定义了接口和绑定后,接下来就要定义服务了(请参见清单 22)。


清单 22. 定义服务
                    
...
<wsdl:binding name="ClassifiedServiceBinding" 
                     type="tns:ClassifiedServicePortType">

...
</wsdl:binding>

<wsdl:service name="ClassifiedService">
  <wsdl:port name="ClassifiedServicePort" 
                    binding="tns:ClassifiedServiceBinding">
    <soap:address location=
 "http://127.0.0.1:8080/axis2/services/ClassifiedService" />
  </wsdl:port>
</wsdl:service>

</wsdl:definitions>

service 可以具有多个端点,每个端点都由其自己对应的 port 元素进行定义。port 元素与特定绑定对应,包括有关如何访问此绑定的信息。在本例中,Larry 指定可以通过 SOAP 在以下位置访问该端口:http://127.0.0.1:8080/axis2/services/ClassifiedService





回页首


为服务添加注释

定义了服务后,还要进行一个步骤。虽然是可选的,但真的应该进行此步骤。WSDL 允许您向 WSDL 文档中的任何元素添加 documentation 元素。清单 23 提供了一个示例。


清单 23. 为服务添加注释
                    
...
<wsdl:portType name="ClassifiedServicePortType">

  <wsdl:document>The finalizeIssue operation is an "in-only"
         operation that tells the system not to accept any 
         more ads for a particular date.</wsdl:document>

  <wsdl:operation name="finalizeIssue">
    <wsdl:input message="tns:finalizeIssueRequestMessage" />
  </wsdl:operation>
...

有关 WSDL 的知识还有很多,但上面这些是基本的内容。不过,继续学习本教程之前,让我们了解一些您可能遇到的更为复杂的情况。





回页首


绑定 SOAP over HTTP 之外的其他协议

尽管 WSDL 的最常见用法是定义 SOAP over HTTP,但却不是指定 Web 服务的唯一方法。例如,Larry 可以创建一个使用 SOAP over E-mail 的绑定,并仅为 finalizeIssue 操作启用它(请参见清单 24)。


清单 24. 添加其他绑定
                    
...
<wsdl:binding name="ClassifiedServiceEmailBinding" 
                          type="tns:ClassifiedServicePortType">

   <soap:binding style="document" transport="http://example.com/smtp"/>

   <wsdl:operation name="finalizeIssue">
     <wsdl:input message="tns:finalizeIssueRequestMessage">
         <soap:body parts="body" use="literal"/>
      </wsdl:input>
   </wsdl:operation>

</wsdl:binding>

<wsdl:service name="ClassifiedService">
  <wsdl:port name="ClassifiedServicePort" 
                    binding="tns:ClassifiedServiceBinding">
    <soap:address location=
       "http://127.0.0.1:8080/axis2/services/ClassifiedService" />
  </wsdl:port>

  <wsdl:port name="ClassifiedServiceEmailPort" 
                       binding="tns:ClassifiedServiceEmailBinding">
    <soap:address location="mailto:finalizeIssue@daily-moon.com" />
  </wsdl:port>
</wsdl:service>

</wsdl:definitions>

此处 Larry 添加了第二个绑定 ClassifiedServiceEmailBinding。和 ClassifiedServiceBinding 绑定一样,此绑定基于 ClassifiedServicePortType portType。不过,在本例中,他使用的是 SMTP(用于发送电子邮件的协议),而不是 HTTP。他可以随后向服务添加第二个端口,使其基于新绑定,使用电子邮件 URL 作为地址,而不是 HTTP URL。您可以为单个服务创建任意多的端口。





回页首


SOAP 和 Mime

另一个与此解决方案有关的主题还不甚明显,即将 SOAP 用于附件。由于消息不仅是 XML 文档,您应该如何使用 WSDL 进行指定呢?这个问题的答案涉及到一个事实,即消息是使用“多部分 MIME”发送的。幸运的是,您可以在 WSDL 文档中指定这一点。例如,Larry 希望指定一个操作,通过此操作,用户可以编辑从广告的 PDF 校样获得的现有广告(请参见清单 25)。


>清单 25. 指定包含多个部分的消息
                    
...
  <wsdl:operation name="editExistingAd">
    <soap:operation soapAction="editExistingAd" 
style="document" />
    <wsdl:input>
      <soap:body use="literal" 
                namespace="http://daily-moon.com/classifieds" />
    </wsdl:input>
    <wsdl:output>
      <soap:body use="literal" 
                namespace="http://daily-moon.com/classifieds" />
      <mime:multipartRelated>
          <mime:part>
             <soap:body parts="body" use="literal"/>
          </mime:part>
          <mime:part>
              <mime:content part="docs" type="text/html"/>
          </mime:part>
          <mime:part>
              <mime:content part="proof" type="image/gif"/>
              <mime:content part="proof" type="image/jpeg"/>
           </mime:part>
       </mime:multipartRelated>
    </wsdl:output>
...

在本例中,返回消息包含 SOAP、一个 HTML 文档和两个图像文件。





回页首


WSDL 2.0 中包含的新内容

在此部分中,我尽力说明 WSDL 2.0 与 WSDL 1.1 的一些不同之处,如从可能出现多个 portType 的情况变为单个 interface,以及 message 不再能包含多个部分等。其他方面也有一定程度的调整。

有多个因素促成了这些更改,但大部分更改的目的都是为了提高互操作性——不符合 WS-I 基本概要 (WS-I Basic Profile) 的构造通常都禁止使用——或为了更方便地将 WSDL 与经过扩展的 SOAP 规范一起使用。例如,WSDL 2.0 更多使用的是“组件”模型,此模型更适合与 WS-Choreography 等规范的要求进行集成。

另一个更改与“消息交换模式”的正式规范有关。WSDL 2.0 不依赖于用户确定是同时存在输入和输出还是仅有一个输入消息,它允许您具体地声明所使用的模式(请参见清单 26)。


清单 26. 指定消息交换模式
                    
...
  <wsdl:operation name="finalizeIssue"
            pattern=http://www.w3.org/2006/01/wsdl/in-only">
    <wsdl:input message="tns:finalizeIssueRequestMessage" />
  </wsdl:operation>

  <wsdl:operation name="createNewAd"
              pattern="http://www.w3.org/2006/01/wsdl/in-out">
    <wsdl:input message="tns:createNewAdRequestMessage" />
    <wsdl:output message="tns:createNewAdResponseMessage" />
  </wsdl:operation>
...

现在让我们深入了解一下 WSDL 样式。





回页首

posted on 2006-12-29 19:09 SIMONE 阅读(1616) 评论(0)  编辑  收藏 所属分类: AXISJAVA

只有注册用户登录后才能发表评论。


网站导航: