CXF wsdl2java导致BINDING_MISSING_TYPE

时间:2011-06-27 07:03:27

标签: java validation wsdl cxf

使用java 6,CXF 2.3.1和Maven 2。

当通过Maven插件运行CXF wsdl2java工具时,我遇到了 以下问题:

  

wsdl2java -d   C:\ devel \ adpoint_callback \ target \ generated-sources \ cxf -impl -validate -verbose file:/ C:/devel/adpoint_callback/src/main/resources/wsdl/foobar.wsdl   wsdl2java - Apache CXF 2.3.1

     

发现WSIBP Validator< binding>不是   SOAP绑定[DEBUG]

     

org.apache.cxf.tools.common.ToolException:   org.apache.cxf.wsdl11.WSDLRuntimeException:   BINDING_MISSING_TYPE           在org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:279)

     

...... ~20行

     

引起:org.apache.cxf.wsdl11.WSDLRuntimeException:BINDING_MISSING_TYPE           在org.apache.cxf.wsdl11.WSDLServiceBuilder.buildServices(WSDLServiceBuilder.java:306)           在org.apache.cxf.wsdl11.WSDLServiceBuilder.buildServices(WSDLServiceBuilder.java:181)

使用从http://www.w3schools.com/WSDL/wsdl_binding.asp改编的以下最小WSDL文件:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="notification"   
    targetNamespace="http://example.com/mynamespace" 
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsd="http://example.com/mynamespace/xsd" >

    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
            xmlns:xsd="http://example.com/mynamespace/xsd" 
            targetNamespace="http://example.com/mynamespace/xsd" >
            <xs:element name="RequestType" type="xsd:content"/>
            <xs:element name="ResponseType" type="xsd:content"/>

            <xs:complexType name="content">
                    <xs:sequence>
                        <xs:element name="text" type="xs:string"/>
                    </xs:sequence>
            </xs:complexType>
        </xs:schema>
    </wsdl:types>

    <wsdl:message name="getTermRequest">
        <wsdl:part name="body" element="xsd:RequestType"/>
    </wsdl:message>

    <wsdl:message name="getTermResponse">
        <wsdl:part name="body" element="xsd:ResponseType"/>
    </wsdl:message>

    <wsdl:portType name="glossaryTerms">
        <wsdl:operation name="getTerm">
            <wsdl:input message="getTermRequest"/>
            <wsdl:output message="getTermResponse"/>
        </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="binding" type="glossaryTerms">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="getTerm">
            <soap:operation soapAction="http://example.com/getTerm" />
            <wsdl:input><soap:body use="literal"/></wsdl:input>
            <wsdl:output><soap:body use="literal"/></wsdl:output>
        </wsdl:operation>
    </wsdl:binding>

    <wsdl:service name="testService" >
        <wsdl:port name="testPort" binding="binding">
            <soap:address location="http://example.com/mynamespace"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

服务/绑定用法与WSDL 1.1规范文档http://www.w3.org/TR/wsdl中的示例中使用的完全相同

如果没有-validate标志,代码生成将无法工作 - 验证警告不会显示。

问题 - 当然 - 为什么&lt; soap:binding&gt;不接受元素作为绑定元素的绑定类型。


[编辑:修正]

如果我将默认命名空间设置为与targetNamespace相同的值,则错误消失。 不知何故,CXF能够处理这样一个事实:我没有设置默认命名空间,直到应该处理绑定为止。在那一点上,它抛出了一个关于缺失绑定类型的误导性异常。

因此,修复它就像更改wsdl:definition标记的属性一样简单 定义默认命名空间:

<wsdl:definitions name="notification"   
    targetNamespace="http://example.com/mynamespace" 
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsd="http://example.com/mynamespace/xsd"
        xmlns="http://example.com/mynamespace" >

1 个答案:

答案 0 :(得分:0)

当您使用targetNamespace="http://example.com/mynamespace"并定义您的绑定时:

<wsdl:binding name="binding" type="glossaryTerms">
    ...
</wsdl:binding>    

然后你必须在wsdl:service部分中引用具有相应命名空间的绑定。具体来说,它应该是:binding="<namespace>:<binding_name>"。这意味着您必须定义与targetNamespace相同的名称空间。例如,命名空间 tns

<wsdl:definitions name="notification"   
    targetNamespace="http://example.com/mynamespace" 
    ...
    xmlns:tns="http://example.com/mynamespace">

然后,在wsdl:service部分引用它时:

<wsdl:service name="testService">
    <wsdl:port name="testPort" binding="tns:binding">
        <soap:address location="http://example.com/mynamespace"/>
    </wsdl:port>
</wsdl:service>