Xifre、Axis2与W3C"WSDL 1.1 Binding Extension for SOAP 1.2"

不同的Webservices实现架构对标准的实现上确实存在诸多的不同,这就是我们在联调系统的时候时常发现无法调通的关键。本文讨论的就是其中的一支,关于Xfire、Axi2在执行W3C "WSDL 1.1 Binding Extension for SOAP 1.2"时的差异,了解了这些有助于我们发现问题,解决问题。

开始之前,需要做些准备:
1、W3C"WSDL 1.1 Binding Extension for SOAP 1.2",可在http://www.w3.org/Submission/wsdl11soap12/ 获得
2、W3C Team Comment on "WSDL 1.1 Binding Extension for SOAP 1.2",可在http://www.w3.org/Submission/2006/05/Comment获得
3、Xfire1.26安装包(安装过程略)
4、Axis2/Java 1.3安装包(安装过程略)
5、一个TcpTrace,我用的这个http://www.pocketsoap.com/tcpTrace/
6、编写Xfire服务端程序,支持SOAP1.2。详见http://blog.youkuaiyun.com/leo_fanaq/archive/2008/01/26/2067366.aspx
7、Axis2/Java 1.3使用自带例子StockQuoteService
8、Xfire1.26、Axis2/Java 1.3默认是使用WSDL1.1,不做调整。

准备工作就绪后,我们开始工作:
1、W3C对WSDL1.1绑定SOAP1.2的规范中,有如下阐述:

1、Provide functionality comparable to binding for SOAP 1.1 [WSDL 1.1] for SOAP 1.2 [SOAP 1.2 Part 1, Part 2]. Specifically: 
    1)Indicate that a binding is bound to the SOAP 1.2 protocol. 
    2)Specify an address for a SOAP endpoint. 
    3)Specify the URI for the action parameter of the application/soap+xml Content-Type HTTP header value [SOAP Media] for the HTTP binding of SOAP. 
    4)Define Headers that are transmitted as part of the SOAP Envelope. 
2、Indicate whether an action parameter is required by a SOAP 1.2 endpoint. 
3、Provide extensibility for more sophisticated and/or currently unanticipated scenarios. 

以上这些是W3C在WSDL1.1基础上扩展对SOAP1.2的支持的必要条件,我们分别与Xfire、Axis2/Java生成的WSDL做比较分析。

The XML Namespace URI that MUST be used by implementations of this specification is:
         http://schemas.xmlsoap.org/wsdl/soap12/

Table 2 lists XML namespaces that are used in this specification. The choice of any namespace prefix is arbitrary and not semantically significant.

Table 2: Prefixes and XML Namespaces used in this specification.

Prefix                         XML Namespace                                    Specification(s)

wsdl                   http://schemas.xmlsoap.org/wsdl/                  [WSDL 1.1]
------------------------------------------------------------------------------------------------------------------------- 
wsoap12            http://schemas.xmlsoap.org/wsdl/soap12/ This specification
   -------------------------------------------------------------------------------------------------------------------------
    xs                      http://www.w3.org/2001/XMLSchema       [XML Schema Part 1, Part 2]
------------------------------------------------------------------------------------------------------------------------- 
soap                  http://www.w3.org/2003/05/soap-envelope  [SOAP 1.2]

这个估计是现在制约系统间联通的最表象的、也是最关键的问题,另外关于这部分W3C也出了一份额外的解释:W3C Team Comment on "WSDL 1.1 Binding Extension for SOAP 1.2"。

A characteristic of this SOAP 1.2 binding of WSDL 1.1 is that it uses the http://schemas.xmlsoap.org/soap/http URI as the identifier for HTTP as the transport of SOAP; this is the URI which was introduced by WSDL 1.1 to identify the SOAP 1.1 HTTP binding. This is interesting as the SOAP 1.2 HTTP binding defines a URI for its identification (http://www.w3.org/2003/05/soap/bindings/HTTP/) already, and Architecture of the World Wide Web, Volume One points out that URI aliases should be avoided.

但是在W3C的另外一份文件(http://schemas.xmlsoap.org/wsdl/soap12/)中是这样说的,真是有混淆视听之嫌:

WSDL 1.1 Binding Extension for SOAP 1.2
March 2006

Introduction
This document describes a directory of links to resources related to the WSDL 1.1 Binding Extension for SOAP 1.2.
……
Specification:
……
Note: The example uses a preliminary value for the encodingStyle attribute. The final value is "http://www.w3.org/2003/05/soap-encoding" per SOAP Version 1.2 Part 2: Adjuncts. 



另外关于prefix,我不是教条主义者,自定义也无妨。

< wsdl:definitions  ... >

    ...

    
< wsdl:binding  ... >
        
< wsoap12:binding  style ="rpc|document"  ? transport ="xs:anyURI"
            wsdl:required
="xs:boolean"  ?  />
        
< wsdl:operation  ... >
            
< wsoap12:operation  soapAction ="xs:anyURI"  ?
                soapActionRequired
="xs:boolean"  ? style ="rpc|document"  ?
                wsdl:required
="xs:boolean"  ?  />    ?
            
< wsdl:input >
                
< wsoap12:body  parts ="wsoap12:tParts"  ?
                    use
="literal|encoded"  ? encodingStyle ="xs:anyURI"  ?
                    namespace
="xs:anyURI"  ? wsdl:required ="xs:boolean"  ?  />
                
< wsoap12:header  message ="xs:QName"  part ="xs:NMTOKEN"
                    use
="literal|encoded"  encodingStyle ="xs:anyURI"  ?
                    namespace
="xs:anyURI"  ? wsdl:required ="xs:boolean"  ? >
                    
< wsoap12:headerfault  message ="xs:QName"
                        part
="xs:NMTOKEN"  use ="literal|encoded"  encodingStyle ="xs:anyURI"  ?
                        namespace
="xs:anyURI"  ? wsdl:required ="xs:boolean"  ?  />     *
                
</ wsoap12:header >     *
            
</ wsdl:input >     ?
            
< wsdl:output >
                
<!--  Same as wsdl:input  -->
            
</ wsdl:output >      ?
            
< wsdl:fault >
                
< wsoap12:fault  name ="xs:NMTOKEN"  use ="literal | encoded"
                    encodingStyle
="xs:anyURI"  ? namespace ="xs:anyURI"  ?
                    wsdl:required
="xs:boolean"  ?  />
            
</ wsdl:fault >       *
        
</ wsdl:operation >       *
    
</ wsdl:binding >    *

    
< wsdl:service  ... >
        
< wsdl:port  ... >
            
< wsoap12:address  location ="xs:anyURI"
                wsdl:required
="xs:boolean"  ?  />
        
</ wsdl:port >      *
    
</ wsdl:service >     *

</ wsdl:definitions >

     这部分是现在很多WSDL2JAVA无法生成客户端的原因所在,"?" (0 or 1) "*" (0 or more) "+" (1 or more) 。


2、首先看Xfire生成的WSDL1.1绑定SOAP1.2报文(如果<property name="createDefaultBindings" value="true" />则通过WSDL地址获取到的是SOAP1.1的报文,但SOAP1.2还是可以使用的)
      W3C建议在WSDL1.1基础上对SOAP1.2进行扩展支持,但不同于Axis2/Java执行标准,Xfire使用了不同的处理方法,将SOAP1.1绑定与SOAP1.2绑定分割开来,但对SOAP1.2所生成的WSDL还是1.1版本。这样不得不讲是便利于用户的,用户可以自行选择是否开启SOAP1.1亦或SOAP1.2,而不像Axis2/Java只支持通过distableSOAP12参数关闭对SOAP1.2的支持。这里我给Xfire加分,虽然它不符合W3C标准。
      接下来我们看看报文详情:

<? xml version="1.0" encoding="UTF-8" ?>
< wsdl:definitions
    
targetNamespace ="http://interfaces.service.web.readyesb"
    xmlns:tns
="http://interfaces.service.web.readyesb"
    xmlns:wsdlsoap
="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:soap12
="http://www.w3.org/2003/05/soap-envelope"<!--NO W3C-->
    xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
    xmlns:soapenc11
="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soapenc12
="http://www.w3.org/2003/05/soap-encoding"
    xmlns:soap11
="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:wsdl
="http://schemas.xmlsoap.org/wsdl/" ><!--WSDL1.1-->
    
< wsdl:types >
        
< xsd:schema  attributeFormDefault ="qualified"
            elementFormDefault
="qualified"
            targetNamespace
="http://interfaces.service.web.readyesb"
            xmlns:xsd
="http://www.w3.org/2001/XMLSchema" >
            
< xsd:element  name ="CheckXXXPWD" >
                
< xsd:complexType >
                    
< xsd:sequence >
                        
< xsd:element  maxOccurs ="1"  minOccurs ="1"
                            name
="in0"  nillable ="true"  type ="xsd:string"   />
                        
< xsd:element  maxOccurs ="1"  minOccurs ="1"
                            name
="in1"  nillable ="true"  type ="xsd:string"   />
                        
< xsd:element  maxOccurs ="1"  minOccurs ="1"
                            name
="in2"  nillable ="true"  type ="xsd:string"   />
                        
< xsd:element  maxOccurs ="1"  minOccurs ="1"
                            name
="in3"  nillable ="true"  type ="xsd:string"   />
                    
</ xsd:sequence >
                
</ xsd:complexType >
            
</ xsd:element >
            
< xsd:element  name ="CheckXXXPWDResponse" >
                
< xsd:complexType >
                    
< xsd:sequence >
                        
< xsd:element  maxOccurs ="1"  minOccurs ="1"
                            name
="out"  nillable ="true"  type ="xsd:string"   />
                    
</ xsd:sequence >
                
</ xsd:complexType >
            
</ xsd:element >
        
</ xsd:schema >

    
</ wsdl:types >
    
< wsdl:message  name ="CheckXXXPWDRequest" >
        
< wsdl:part  name ="parameters"  element ="tns:CheckXXXPWD" >
        
</ wsdl:part >
    
</ wsdl:message >
    
< wsdl:message  name ="CheckXXXPWDResponse" >
        
< wsdl:part  name ="parameters"
            element
="tns:CheckXXXPWDResponse" >
        
</ wsdl:part >
    
</ wsdl:message >
    
< wsdl:portType  name ="XXXPWDServicePortType" >
        
< wsdl:operation  name ="CheckXXXPWD" >
            
< wsdl:input  name ="CheckXXXPWDRequest"
                message
="tns:CheckXXXPWDRequest" >
            
</ wsdl:input >
            
< wsdl:output  name ="CheckXXXPWDResponse"
                message
="tns:CheckXXXPWDResponse" >
            
</ wsdl:output >
        
</ wsdl:operation >
    
</ wsdl:portType >
        <!--NO W3C, wsdl:binding is MUST for SOAP1.2 with WSDL1.1-->

    
< wsdl:service  name ="XXXPWDService" >
        <!--NO W3C,wsdl:port is NUST for SOAP1.2 with WSDL1.1-->
        </
wsdl:service >
</ wsdl:definitions >
3、我们再看Axis2/Java生成的WSDL1.1绑定SOAP1.2报文(默认为混合报文,含有SOAP1.1部分),较为死板:),基本按照W3C行事。
<? xml version="1.0" encoding="UTF-8" ?>
< wsdl:definitions  xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/"
    xmlns:axis2
="http://quickstart.samples/"
    xmlns:mime
="http://schemas.xmlsoap.org/wsdl/mime/"
    xmlns:ns0
="http://quickstart.samples/xsd"
    xmlns:soap12
="http://schemas.xmlsoap.org/wsdl/soap12/"<!--YES W3C-->
    xmlns:http
="http://schemas.xmlsoap.org/wsdl/http/"
    xmlns:ns1
="http://org.apache.axis2/xsd"
    xmlns:wsaw
="http://www.w3.org/2006/05/addressing/wsdl"
    xmlns:xs
="http://www.w3.org/2001/XMLSchema"
    xmlns:soap
="http://schemas.xmlsoap.org/wsdl/soap/"<!--WSDL1.1-->
    targetNamespace
="http://quickstart.samples/" >
    
< wsdl:documentation > StockQuoteService </ wsdl:documentation >
    
< wsdl:types >
        
< xs:schema  xmlns:ns ="http://quickstart.samples/xsd"
            attributeFormDefault
="qualified"  elementFormDefault ="qualified"
            targetNamespace
="http://quickstart.samples/xsd" >
            
< xs:element  name ="getPrice" >
                
< xs:complexType >
                    
< xs:sequence >
                        
< xs:element  minOccurs ="0"  name ="symbol"
                            nillable
="true"  type ="xs:string"   />
                    
</ xs:sequence >
                
</ xs:complexType >
            
</ xs:element >
            
< xs:element  name ="getPriceResponse" >
                
< xs:complexType >
                    
< xs:sequence >
                        
< xs:element  minOccurs ="0"  name ="return"
                            type
="xs:double"   />
                    
</ xs:sequence >
                
</ xs:complexType >
            
</ xs:element >
            
< xs:element  name ="update" >
                
< xs:complexType >
                    
< xs:sequence >
                        
< xs:element  minOccurs ="0"  name ="symbol"
                            nillable
="true"  type ="xs:string"   />
                        
< xs:element  minOccurs ="0"  name ="price"
                            type
="xs:double"   />
                    
</ xs:sequence >
                
</ xs:complexType >
            
</ xs:element >
        
</ xs:schema >
    
</ wsdl:types >
    
< wsdl:message  name ="updateRequest" >
        
< wsdl:part  name ="parameters"  element ="ns0:update"   />
    
</ wsdl:message >
    
< wsdl:message  name ="getPriceRequest" >
        
< wsdl:part  name ="parameters"  element ="ns0:getPrice"   />
    
</ wsdl:message >
    
< wsdl:message  name ="getPriceResponse" >
        
< wsdl:part  name ="parameters"  element ="ns0:getPriceResponse"   />
    
</ wsdl:message >
    
< wsdl:portType  name ="StockQuoteServicePortType" >
        
< wsdl:operation  name ="update" >
            
< wsdl:input  message ="axis2:updateRequest"
                wsaw:Action
="urn:update"   />
        
</ wsdl:operation >
        
< wsdl:operation  name ="getPrice" >
            
< wsdl:input  message ="axis2:getPriceRequest"
                wsaw:Action
="urn:getPrice"   />
            
< wsdl:output  message ="axis2:getPriceResponse"
                wsaw:Action
="urn:getPriceResponse"   />
        
</ wsdl:operation >
    
</ wsdl:portType >
    
< wsdl:binding  name ="StockQuoteServiceSOAP11Binding"
        type
="axis2:StockQuoteServicePortType" ><!--YES W3C-->
        
< soap:binding  transport ="http://schemas.xmlsoap.org/soap/http"
            style
="document"   />
        
< wsdl:operation  name ="update" >
            
< soap:operation  soapAction ="urn:update"  style ="document"   />
            
< wsdl:input >
                
< soap:body  use ="literal"   />
            
</ wsdl:input >
        
</ wsdl:operation >
        
< wsdl:operation  name ="getPrice" >
            
< soap:operation  soapAction ="urn:getPrice"  style ="document"   />
            
< wsdl:input >
                
< soap:body  use ="literal"   />
            
</ wsdl:input >
            
< wsdl:output >
                
< soap:body  use ="literal"   />
            
</ wsdl:output >
        
</ wsdl:operation >
    
</ wsdl:binding >
    
< wsdl:binding  name ="StockQuoteServiceSOAP12Binding"
        type
="axis2:StockQuoteServicePortType" >
        
< soap12:binding  transport ="http://schemas.xmlsoap.org/soap/http"
            style
="document"   />
        
< wsdl:operation  name ="update" >
            
< soap12:operation  soapAction ="urn:update"  style ="document"   />
            
< wsdl:input >
                
< soap12:body  use ="literal"   />
            
</ wsdl:input >
        
</ wsdl:operation >
        
< wsdl:operation  name ="getPrice" >
            
< soap12:operation  soapAction ="urn:getPrice"
                style
="document"   />
            
< wsdl:input >
                
< soap12:body  use ="literal"   />
            
</ wsdl:input >
            
< wsdl:output >
                
< soap12:body  use ="literal"   />
            
</ wsdl:output >
        
</ wsdl:operation >
    
</ wsdl:binding >
    
< wsdl:binding  name ="StockQuoteServiceHttpBinding"
        type
="axis2:StockQuoteServicePortType" >
        
< http:binding  verb ="POST"   />
        
< wsdl:operation  name ="update" >
            
< http:operation  location ="StockQuoteService/update"   />
            
< wsdl:input >
                
< mime:content  type ="text/xml"  part ="update"   />
            
</ wsdl:input >
        
</ wsdl:operation >
        
< wsdl:operation  name ="getPrice" >
            
< http:operation  location ="StockQuoteService/getPrice"   />
            
< wsdl:input >
                
< mime:content  type ="text/xml"  part ="getPrice"   />
            
</ wsdl:input >
            
< wsdl:output >
                
< mime:content  type ="text/xml"  part ="getPrice"   />
            
</ wsdl:output >
        
</ wsdl:operation >
    
</ wsdl:binding >
    
< wsdl:service  name ="StockQuoteService" ><!--YES W3C-->
        
< wsdl:port  name ="StockQuoteServiceSOAP11port_http"
            binding
="axis2:StockQuoteServiceSOAP11Binding" >
            
< soap:address
                
location ="http://localhost:7001/ReadyESB_WEB/services/StockQuoteService"   />
        
</ wsdl:port >
        
< wsdl:port  name ="StockQuoteServiceSOAP12port_http"
            binding
="axis2:StockQuoteServiceSOAP12Binding" >
            
< soap12:address
                
location ="http://localhost:7001/ReadyESB_WEB/services/StockQuoteService"   />
        
</ wsdl:port >
        
< wsdl:port  name ="StockQuoteServiceHttpport"
            binding
="axis2:StockQuoteServiceHttpBinding" >
            
< http:address
                
location ="http://localhost:7001/ReadyESB_WEB/services/StockQuoteService"   />
        
</ wsdl:port >
    
</ wsdl:service >
</ wsdl:definitions >

        综上所述,我们可以看到Xfire就像一只桀骜不驯的“野马”,做事并非规矩,然而Axis2显得中庸的多。对于在项目中如何选择,我更倾向于中庸的做法,毕竟是多个厂家协调的事情,还是有一套国际认可的标准为宜。以后我们还会分析WSDL2.0下各家架构的异同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值