使用没有“wsimport”的XML SOAP Web服务

时间:2016-01-07 22:33:54

标签: java xml wcf soap wsimport

我的问题类似于以下帖子中的问题:Consume XML SOAP Webservice in Java。基本上我的问题是用wsimport生成客户端代码并没有真正失败但是生成警告“[WARNING] Port”reqReplyEndpoint“不包含任何可用的操作”。这导致代码生成不完整,例如我在生成的请求/响应类中缺少参数。它是在IIS上托管的WCF服务,它使用WCF消息路由服务。 IIS将所有服务请求路由到端点。我无法控制这项服务,我只需要参与其中。任何想法如何在没有工作的wsimport的情况下实现这一点,例如aksappy提到的方法?是否有可用的框架,样品?对于上面提到的解决方案方法,使用模式验证器在运行时检查WSDL,然后基于它具有单独的解析机制?

1 个答案:

答案 0 :(得分:0)

刚检查过你的包裹。

您的WSDL包含两个服务,一个名为reqReplyEndpoint,另一个名为BasicHttpBinding_TestTableService。我很确定,你想继续使用BasicHttpBinding_TestTableService,因为另一个在其中有空定义(没有定义操作等,请参阅xppservice-wsdl0.xml)

因此: "[WARNING] Port "reqReplyEndpoint" does not contain any usable operations"不是空TestTableServiceGetListRequest的原因。这是两个独立的wsdl:服务,两者之间没有直接关系。抛出此警告,因为名称为“reqReplyEndpoint”的绑定指向名为“IRequestReplyRouter”的端口类型,其中包含空定义(仅将内容xppservice-wsdl0.xml与xppservice-wsdl1.xml进行比较)。 其原因必须是代码中的某个地方,我不是C#WSDL专家(但我在WSDL / Web服务方面经验丰富)。

下一步: 您的WSDL包含三个名称操作:   createMember   deleteMember   的GetList

getList的WSDL结果(SOAP env)根据soapUI:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dat="http://schemas.microsoft.com/dynamics/2010/01/datacontracts" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ser="http://ax.bernina.com/01/services">
   <soapenv:Header>
      <dat:CallContext>
         <!--Optional:-->
         <dat:Company>?</dat:Company>
         <!--Optional:-->
         <dat:Language>?</dat:Language>
         <!--Optional:-->
         <dat:LogonAsUser>?</dat:LogonAsUser>
         <!--Optional:-->
         <dat:MessageId>?</dat:MessageId>
         <!--Optional:-->
         <dat:PropertyBag>
            <!--Zero or more repetitions:-->
            <arr:KeyValueOfstringstring>
               <arr:Key>?</arr:Key>
               <arr:Value>?</arr:Value>
            </arr:KeyValueOfstringstring>
         </dat:PropertyBag>
      </dat:CallContext>
   </soapenv:Header>
   <soapenv:Body>
      <ser:TestTableServiceGetListRequest/>
   </soapenv:Body>
</soapenv:Envelope>

你看,ser:TestTableServiceGetListRequest是空的,因为底层的基础xsd(xppservice-xsd3.xml)包含一个空的定义:

   <xs:element name="TestTableServiceGetListRequest">
      <xs:complexType>
         <xs:sequence/>
      </xs:complexType>
   </xs:element>

如果你期望TestTableServiceGetListRequest中有更多的参数,你应该检查相应的源代码(它负责WSDL结果 - 我不是在讨论wsimport结果),如果有缺少的东西(注释或类似)。

另外:我建议首先采用契约优先设计(首先创建WSDL,然后从中生成代码),而不是代码优先设计,因为如您所见,代码的结果可能与预期不一样并且搜索代码中的根本原因可能很困难。

修改1 关于评论中的问题1:

如果要将CallContext从soap:标头移动到soap:body中,需要在wsdl(xppservice-wsdl.xml)中更改以下内容:

在:

 <wsdl:operation name="getList">
         <soap:operation soapAction="http://ax.bernina.com/01/services/TestTableService/getList" style="document"/>
         <wsdl:input name="TestTableServiceGetListRequest">
            <soap:header message="i1:TestTableServiceGetListRequest_Headers" part="context" use="literal"/>
            <soap:body use="literal"/>
         </wsdl:input>
         <wsdl:output name="TestTableServiceGetListResponse">
            <soap:body use="literal"/>
         </wsdl:output>
         <wsdl:fault name="AifFaultFault">
            <soap:fault name="AifFaultFault" use="literal"/>
         </wsdl:fault>
      </wsdl:operation>

后:

 <wsdl:operation name="getList">
         <soap:operation soapAction="http://ax.bernina.com/01/services/TestTableService/getList" style="document"/>
         <wsdl:input name="TestTableServiceGetListRequest">
            <soap:body message="i1:TestTableServiceGetListRequest_Headers" part="context" use="literal"/>
         </wsdl:input>
         <wsdl:output name="TestTableServiceGetListResponse">
            <soap:body use="literal"/>
         </wsdl:output>
         <wsdl:fault name="AifFaultFault">
            <soap:fault name="AifFaultFault" use="literal"/>
         </wsdl:fault>
      </wsdl:operation>