相同的SOAP Web服务需要Java不同的参数类型?

时间:2015-03-28 22:18:24

标签: java soap jax-ws

我有一个Web Service客户端,用于2个相同的SOAP Web服务,名为Company1Service和Company2Service。这两个Web服务都具有完全相同的PurchaseOrder类。

但是,当我想从每个Web服务调用m1ProcessPurchaseOrder()方法和m2ProcessPurchaseOrder()方法时,它们需要Po对象的不同参数类型。然而,PurchaseOrder类对于两种服务都是相同的。

我正在使用NetBeans和Generated Sources(jax-ws)。

public boolean m1ProcessPurchaseOrder(ab.service.company1.PurchaseOrder Po) 
{
    ab.service.company1.Company1Service port = service1.getComapny1ServicePort();
    return port.processPurchaseOrder(po);
}

public boolean m2ProcessPurchaseOrder(ab.service.company2.PurchaseOrder Po) 
{
    ab.service.company2.Company2Service port = service2.getComapny2ServicePort();
    return port.processPurchaseOrder(po);
}

我想要做的是ab.service.company1.PurchaseOrder是Company1Service和Company2Service的参数类型。

如果我尝试将m2ProcessPurchaseOrder()参数类型更改为ab.service.company1.PurchaseOrder,则出现此错误:

  

接口Company2Service中的方法processPurchaseOrder不能应用于给定类型;

     

必需:ab.service.Company2.PurchaseOrder

     

找到:ab.service.Company1.PurchaseOrder

     

原因:实际参数ab.service.Company1.PurchaseOrder无法通过方法调用转换转换为ab.service.Company2.PurchaseOrder

1 个答案:

答案 0 :(得分:1)

取决于您正在使用的 JAX-WS 实现 - 有几个: CXF RI / Metro Axis2 JBossWS Spring-WS 等 - 您可能需要调用不同的工具来生成工件( XSD 模式或 WSDL ),即RI的 wsimport ,或特定的JAX-WS实现工具,如* Axis * 2或 CXF WSDL2Java ,或 JBossWS ' wsprovide

此外,根据您为项目设置的构建脚本/工具,可能有一个任务,目标或目标可用于自动调用这些工具。然而,当涉及XML到Java绑定时,您可以利用 JAXB 绑定文档来操作生成的Java类,包括操作它们生成的位置(包)。这是通过 jaxb:bindings jaxb 只是名称空间前缀)完成的。对于 WSDL 工件,即服务,您可以将映射指令放在 jaxws:bindings 中(同样在这里 jaxws 是只是一个XML命名空间)。请注意,这两个是两个单独的绑定( XML )文档,可以提供给上述工具之一,即 CXF WSDL2Java 的wsimport

对于 JAXB 绑定,您可以创建类似于(Company1Binding.xml)的绑定文档:

<?xml version="1.0" encoding="UTF-8" ?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1">

  <jaxb:bindings schemaLocation="PurchaseOrder.xsd">
    <jaxb:schemaBindings>
      <jaxb:package name="ab.service.common" />
    </jaxb:schemaBindings>
  </jaxb:bindings>

  <!-- more binding related to Company1Service -->

</jaxb:bindings>

Company2Binding.xml的JAXB绑定:

<?xml version="1.0" encoding="UTF-8" ?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1">

  <jaxb:bindings schemaLocation="PurchaseOrder.xsd">
    <jaxb:schemaBindings>
      <jaxb:package name="ab.service.common" />
    </jaxb:schemaBindings>
  </jaxb:bindings>

  <!-- more binding related to Company2Service -->

</jaxb:bindings>

这会将生成的PurchaseOrder.java类放在ab.service.common包中,因此您可以在此ab.service.company1.*ab.service.company2.*中引用此类的实例({{ 1}})。

请注意,如果您在某个时间点对PurchaseOrder.xsd进行了更改,我会将此类绑定放在Company1和Company2中,并仅生成绑定中的一个服务,即Company1。在这种情况下,为两者重新生成PurchaseOrder.java,因为它只有一个生成的类(ab.service.common.PurchaseOrder.java)。

您可以对 WSDL 工件执行相​​同的操作,例如对于ab.service.common.PurchaseOrder.java,您可以创建一个新的绑定文档,如(Comapny1Service.wsdl):

Company1ServiceBinding.xml

<?xml version="1.0" encoding="UTF-8"?> <jaxws:bindings xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" version="2.1" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" wsdlLocation="Company1Service.wsdl"> <jaxws:bindings node="wsdl:definitions"> <jaxws:package name="ab.service.company1" /> </jaxws:bindings> <jaxws:bindings node="wsdl:definitions/wsdl:portType/wsdl:operation/wsdl:fault[@name='fault']"> <jaxws:class name="ab.service.common.ServiceException" /> </jaxws:bindings> </jaxws:bindings> 包中放置服务类(如接口,客户端代理,以及您在WSDL中为操作指定的Soap Fault类型)。请注意每个绑定文档(ab.service.Company1jaxb:bindings)中的命名空间之间的区别。最后,您可以将这些绑定信息传递给实际工具,即 CXF WSDL2Java (在本例中,来自 Ant 的代码片段)构建文件):

jaxws:bindings

(注意:您应该具有 Company2Service 的类似目标)

如您所见,此特定工具通过<java classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true"> <arg value="-d"/> <arg value="${path.to.generated.code}"/> <arg value="-b"/> <arg value="${path.to.artifacts}/Company1Binding.xml"/> <arg value="-b"/> <arg value="${path.to.artifacts}/Company1ServiceBinding.xml"/> <arg value="${path.to.artifacts}/Company1Service.wsdl"/> <classpath> <path refid="${jaxws.impl.library.path}"/> </classpath> </java> 标志接受绑定文档( JAXB JAX-WS )。事实上,这些工具(如 WSDL2Java )最终调用的Binding Compiler (xjc)确实通过-b选项接受绑定文档(请注意该链接将您带到参考实现/ Metor xjc 版本,但 CXF 和其他'应该接近'。事实上,您可以直接调用 WSDL2Java 本身:

-b

使用 JAXB 进行映射需要让自己熟悉一些细节,但您可以read more about it here JAX-WS RI / Metro 。对于 CXF ,您可以refer to here,以及 CXF WSDL2Java Maven's plugin的一些示例。同样,每个 JAX-WS 实现都有自己的一套工具,但是当涉及与 JAXB 相关联的底层映射/绑定时,这些概念是相同的。