骆驼 CXF Wsdl2java 问题
Camel CXF Wsdl2java issue
我正在尝试使用 Camel 和 CXF 调用第三方 SOAP Web 服务。这是 wsdl
的摘录
<message name="setDeviceDetailsv4">
<part name="parameters" element="tns:setDeviceDetailsv4"></part>
<part name="gdspHeader" element="tns:gdspHeader"></part>
</message>
<message name="setDeviceDetailsv4Response">
<part name="result" element="tns:setDeviceDetailsv4Response"></part>
</message>
<portType name="SetDeviceDetailsv4">
<operation name="setDeviceDetailsv4" parameterOrder="parameters gdspHeader">
<input message="tns:setDeviceDetailsv4"></input>
<output message="tns:setDeviceDetailsv4Response"></output>
</operation>
</portType>
<binding name="SetDeviceDetailsv4PortBinding" type="tns:SetDeviceDetailsv4">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
<operation name="setDeviceDetailsv4">
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal" parts="parameters"></soap:body>
<soap:header message="tns:setDeviceDetailsv4" part="gdspHeader" use="literal"></soap:header>
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
</binding>
<service name="SetDeviceDetailsv4Service">
<port name="SetDeviceDetailsv4Port" binding="tns:SetDeviceDetailsv4PortBinding">
<soap:address location="http://localhost:${HttpDefaultPort}/GDSPWebServices/SetDeviceDetailsv4Service"></soap:address>
</port>
</service>
正如你所看到的,soap body 使用了上面 wsdl 中提到的 "parameters" 部分,与 tns:setDeviceDetailsv4 相关。
示例客户端代码如下所示:
System.out.println("Invoking setDeviceDetailsv4...");
SetDeviceDetailsv4_Type _setDeviceDetailsv4_parameters = null;
GdspHeader _setDeviceDetailsv4_gdspHeader = null;
SetDeviceDetailsv4Response _setDeviceDetailsv4__return = port.setDeviceDetailsv4(_setDeviceDetailsv4_parameters, _setDeviceDetailsv4_gdspHeader);
System.out.println("setDeviceDetailsv4.result=" + _setDeviceDetailsv4__return);
当我通过与上面的客户端代码匹配的 camel 路由进行调用时,我希望 CXF / Camel 将 "gdspHeader" 附加到 soap header 但它没有,它正在发送它作为网络方法的参数。一个单独的开发人员手工编写了 SOAP 调用的代码,这就是他所拥有的并且它完美地工作!!
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.gdsp.xxxxxxx.com/">
<soapenv:Header>
<ws:gdspHeader>
<gdspCredentials>
<userId>xxxx</userId>
<password>xxxx</password>
</gdspCredentials>
</ws:gdspHeader>
</soapenv:Header>
<soapenv:Body>
<ws:setDeviceDetailsv4>
<deviceId>xxxxxx</deviceId>
<state>x</state>
</ws:setDeviceDetailsv4>
</soapenv:Body>
</soapenv:Envelope>
然而,当我通过 Camel 进行调用时,这是我得到的 SOAP 消息:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<ns2:gdspHeader xmlns:ns2="http://ws.gdsp.xxxx.com/">
<gdspCredentials>
<password>xxxx</password>
<userId>xxxx</userId>
</gdspCredentials>
</ns2:gdspHeader>
</soap:Header>
<soap:Body>
<ns1:setDeviceDetailsv4 xmlns:ns1="http://ws.gdsp.Xxxxx.com/">
<ns2:arg0 xmlns:ns2="http://ws.gdsp.xxx.com/">
<deviceId>xxxx</deviceId>
<state>x</state>
</ns2:arg0>
<ns2:arg1 xmlns:ns2="http://ws.gdsp.xxxx.com/">
<gdspCredentials>
<password>xxxx</password>
<userId>xxxx</userId>
</gdspCredentials>
</ns2:arg1>
</ns1:setDeviceDetailsv4>
</soap:Body>
</soap:Envelope>
它失败了。我已尝试使 gdspCredentials 为 NULL,但这不起作用,如果我只传入一个参数,CXF 会抛出一个 soap 错误,指出该方法需要两个参数。
这是我的 pom.xml 文件的一部分
<build>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.7.7</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<frontEnd>jaxws21</frontEnd>
<faultSerialVersionUID>1</faultSerialVersionUID>
<wsdl>src/main/resources/wsdl/extWebServices.wsdl</wsdl>
<extraargs>
<extraarg>-client</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
如何让我的 Camel / CXF 调用与其他开发人员所做的相匹配?
wsdl 不能立即满足我的需要。我能够修改 wsdl 以删除 "header" 选项,并使用拦截器来处理 header 部分,并使用处理器来处理响应和请求编组/解组。
我正在尝试使用 Camel 和 CXF 调用第三方 SOAP Web 服务。这是 wsdl
的摘录<message name="setDeviceDetailsv4">
<part name="parameters" element="tns:setDeviceDetailsv4"></part>
<part name="gdspHeader" element="tns:gdspHeader"></part>
</message>
<message name="setDeviceDetailsv4Response">
<part name="result" element="tns:setDeviceDetailsv4Response"></part>
</message>
<portType name="SetDeviceDetailsv4">
<operation name="setDeviceDetailsv4" parameterOrder="parameters gdspHeader">
<input message="tns:setDeviceDetailsv4"></input>
<output message="tns:setDeviceDetailsv4Response"></output>
</operation>
</portType>
<binding name="SetDeviceDetailsv4PortBinding" type="tns:SetDeviceDetailsv4">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
<operation name="setDeviceDetailsv4">
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal" parts="parameters"></soap:body>
<soap:header message="tns:setDeviceDetailsv4" part="gdspHeader" use="literal"></soap:header>
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
</binding>
<service name="SetDeviceDetailsv4Service">
<port name="SetDeviceDetailsv4Port" binding="tns:SetDeviceDetailsv4PortBinding">
<soap:address location="http://localhost:${HttpDefaultPort}/GDSPWebServices/SetDeviceDetailsv4Service"></soap:address>
</port>
</service>
正如你所看到的,soap body 使用了上面 wsdl 中提到的 "parameters" 部分,与 tns:setDeviceDetailsv4 相关。
示例客户端代码如下所示:
System.out.println("Invoking setDeviceDetailsv4...");
SetDeviceDetailsv4_Type _setDeviceDetailsv4_parameters = null;
GdspHeader _setDeviceDetailsv4_gdspHeader = null;
SetDeviceDetailsv4Response _setDeviceDetailsv4__return = port.setDeviceDetailsv4(_setDeviceDetailsv4_parameters, _setDeviceDetailsv4_gdspHeader);
System.out.println("setDeviceDetailsv4.result=" + _setDeviceDetailsv4__return);
当我通过与上面的客户端代码匹配的 camel 路由进行调用时,我希望 CXF / Camel 将 "gdspHeader" 附加到 soap header 但它没有,它正在发送它作为网络方法的参数。一个单独的开发人员手工编写了 SOAP 调用的代码,这就是他所拥有的并且它完美地工作!!
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.gdsp.xxxxxxx.com/">
<soapenv:Header>
<ws:gdspHeader>
<gdspCredentials>
<userId>xxxx</userId>
<password>xxxx</password>
</gdspCredentials>
</ws:gdspHeader>
</soapenv:Header>
<soapenv:Body>
<ws:setDeviceDetailsv4>
<deviceId>xxxxxx</deviceId>
<state>x</state>
</ws:setDeviceDetailsv4>
</soapenv:Body>
</soapenv:Envelope>
然而,当我通过 Camel 进行调用时,这是我得到的 SOAP 消息:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<ns2:gdspHeader xmlns:ns2="http://ws.gdsp.xxxx.com/">
<gdspCredentials>
<password>xxxx</password>
<userId>xxxx</userId>
</gdspCredentials>
</ns2:gdspHeader>
</soap:Header>
<soap:Body>
<ns1:setDeviceDetailsv4 xmlns:ns1="http://ws.gdsp.Xxxxx.com/">
<ns2:arg0 xmlns:ns2="http://ws.gdsp.xxx.com/">
<deviceId>xxxx</deviceId>
<state>x</state>
</ns2:arg0>
<ns2:arg1 xmlns:ns2="http://ws.gdsp.xxxx.com/">
<gdspCredentials>
<password>xxxx</password>
<userId>xxxx</userId>
</gdspCredentials>
</ns2:arg1>
</ns1:setDeviceDetailsv4>
</soap:Body>
</soap:Envelope>
它失败了。我已尝试使 gdspCredentials 为 NULL,但这不起作用,如果我只传入一个参数,CXF 会抛出一个 soap 错误,指出该方法需要两个参数。
这是我的 pom.xml 文件的一部分
<build>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.7.7</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<frontEnd>jaxws21</frontEnd>
<faultSerialVersionUID>1</faultSerialVersionUID>
<wsdl>src/main/resources/wsdl/extWebServices.wsdl</wsdl>
<extraargs>
<extraarg>-client</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
如何让我的 Camel / CXF 调用与其他开发人员所做的相匹配?
wsdl 不能立即满足我的需要。我能够修改 wsdl 以删除 "header" 选项,并使用拦截器来处理 header 部分,并使用处理器来处理响应和请求编组/解组。