简体   繁体   English

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

[英]Java different parameter type needed for identical SOAP Web Service?

I have a Web Service client for 2 identical SOAP Web Services called Company1Service and Company2Service. 我有一个Web服务客户端,用于2个相同的SOAP Web服务,分别称为Company1Service和Company2Service。 Both these web services have the exact same PurchaseOrder class. 这两个Web服务都具有完全相同的PurchaseOrder类。

However, when I want to call the m1ProcessPurchaseOrder() method and the m2ProcessPurchaseOrder() method from each web service, they require different parameter types for the Po object. 但是,当我想从每个Web服务调用m1ProcessPurchaseOrder()方法和m2ProcessPurchaseOrder()方法时,它们要求Po对象使用不同的参数类型。 Yet, the PurchaseOrder class is identical for both services. 但是,这两种服务的PurchaseOrder类是相同的。

I am using NetBeans and the Generated Sources (jax-ws). 我正在使用NetBeans和生成的源(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);
}

What I would like to do is have ab.service.company1.PurchaseOrder be the parameter type for both the Company1Service and the Company2Service. 我想做的是将ab.service.company1.PurchaseOrder和Company2Service的参数类型。

Here is my error if I try to change m2ProcessPurchaseOrder() parameter type to ab.service.company1.PurchaseOrder : 这是我的错误,如果我试图改变m2ProcessPurchaseOrder()参数类型ab.service.company1.PurchaseOrder

method processPurchaseOrder in interface Company2Service cannot be applied to given types; 接口Company2Service中的processPurchaseOrder方法不能应用于给定类型;

Required: ab.service.Company2.PurchaseOrder 必需:ab.service.Company2.PurchaseOrder

Found: ab.service.Company1.PurchaseOrder 找到:ab.service.Company1.PurchaseOrder

Reason: actual argument ab.service.Company1.PurchaseOrder cannot be converted to ab.service.Company2.PurchaseOrder by method invocation conversion 原因:实际参数ab.service.Company1.PurchaseOrder无法通过方法调用转换转换为ab.service.Company2.PurchaseOrder

Depending on what JAX-WS implementation you are using -- there are severals: CXF , RI/Metro , Axis2 , JBossWS , Spring-WS , etc. -- you might be needing to invoke different tools to generate your artifacts ( XSD Schemas or WSDL 's), ie RI's wsimport , or a specific JAX-WS implementation tools like *Axis*2's or CXF 's WSDL2Java , or JBossWS ' wsprovide . 根据您使用的JAX-WS实现-有几种: CXFRI / MetroAxis2JBossWSSpring-WS。-您可能需要调用不同的工具来生成工件( XSD Schema或WSDL ),即RI的wsimport ,或特定的JAX-WS实现工具,例如* Axis * 2或CXFWSDL2JavaJBossWSwsprovide

Also, depending on what build script/tool you have setup for your project, there might be a task, goal, or a target that you can utilize to automate the invocation of these tools. 另外,根据您为项目设置的构建脚本/工具,可能会有任务,目标或目标可用于自动调用这些工具。 Nevertheless, when it comes to XML-to-Java binding, you can utilize JAXB Binding document(s) to manipulate the generated Java classes including the manipulation of where (package) they are generated into. 但是,当涉及到XML到Java绑定时,您可以利用JAXB Binding文档来处理生成的Java类,包括对其生成到的位置(包)的处理。 This is done via jaxb:bindings ( jaxb is just a namespace prefix). 这是通过jaxb:bindings完成的jaxb只是一个名称空间前缀)。 For WSDL artifacts, ie service, you can place your mapping instructions in jaxws:bindings (same here jaxws is just an XML namespace). 对于WSDL工件(即服务),可以将映射指令放在jaxws:bindings中 (此处jaxws只是XML名称空间)。 Note that these two are two separate binding ( XML ) documents which can be fed to one of the aforementioned tools, ie CXF 's WSDL2Java or wsimport . 请注意,这两个是两个单独的绑定( XML )文档,可以将它们提供给上述工具之一,即CXFWSDL2Javawsimport

For a JAXB binding, you can create a binding document like ( Company1Binding.xml ): 对于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>

and a JAXB binding for Company2Binding.xml : 以及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>

This would place a generated PurchaseOrder.java class in ab.service.common package, so you can reference the instances of this class in ab.service.company1.* and ab.service.company2.* from this single class ( ab.service.common.PurchaseOrder.java ). 这会将一个生成的PurchaseOrder.java类放在ab.service.common包中,因此您可以从单个类( ab.service.common.PurchaseOrder.javaab.service.company1.*ab.service.company2.*引用该类的实例ab.service.company1.* ab.service.common.PurchaseOrder.java )。

Note that I place such binding in both Company1's and Company2's in case you make changes to PurchaseOrder.xsd at some point, and generate the binding only one of the services, ie Company1's. 请注意,如果您在某个时候对PurchaseOrder.xsd进行了更改,则在Company1和Company2中都放置了这种绑定,并且仅生成了其中一项服务即Company1的绑定。 In this case, PurchaseOrder.java is regenerated for both, since there is only one generated class for it ( ab.service.common.PurchaseOrder.java ). 在这种情况下,将为这两个都重新生成PurchaseOrder.java,因为只有一个为它生成的类( ab.service.common.PurchaseOrder.java )。

You can do the same with WSDL artifacts, for example for Comapny1Service.wsdl , you can create a new binding document like ( Company1ServiceBinding.xml ): 您可以对WSDL工件进行相同的操作,例如对于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>

Which would place the service classes (like the interface, client proxy, along side, say, Soap Fault type you specified in your WSDL for the operations) in ab.service.Company1 package. 这会将服务类(例如接口,客户端代理,以及您在WSDL中为操作指定的Soap Fault类型)放在ab.service.Company1包中。 Notice the difference between the namespaces in each binding document ( jaxb:bindings vs. jaxws:bindings ). 注意每个绑定文档中的名称空间之间的差异( jaxb:bindingsjaxws:bindings )。 Finally, you can pass these binding information to the actual tool, ie CXF 's WSDL2Java (in this case, a snippet of code from Ant build file): 最后,您可以将这些绑定信息传递给实际工具,即CXFWSDL2Java (在这种情况下,是来自Ant构建文件的代码片段):

<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>

(NOTE: you should have a similar target for Company2Service ) (注意: Company2Service应该有一个类似的目标)

As you can see, this particular tool accepts binding documents ( JAXB and JAX-WS ) via a -b flag. 如您所见,此特定工具通过-b标志接受绑定文档( JAXBJAX-WS )。 As a matter of fact, the Binding Compiler (xjc) which these tools, like WSDL2Java , ultimately call, do accept the binding documents via -b option (note the link takes you to Reference Implementation/Metor 's version of xjc , but CXF 's and others' should be close). 实际上,这些工具(如WSDL2Java )最终会调用的Binding Compiler(xjc)确实通过-b选项接受了绑定文档(请注意,该链接将您带到Reference Implementation / Metorxjc版本,但使用CXF 's and others'应该接近)。 As a matter of fact, you could have just call the WSDL2Java itself directly: 实际上,您可以直接调用WSDL2Java本身:

/path/to/wsdltojava -d /path/to/where/you/want/to/generate -b /path/to/wsdl/artifacts/CompanyBinding.xml -b /path/to/wsdl/artifacts/Company1ServiceBinding.xml /path/to/wsdl/artifacts/Company1Service.wsdl

Mapping using JAXB requires getting yourself familiarized with a bit of details, but you can read more about it here which is JAX-WS RI/Metro 's. 使用JAXB进行映射需要使您熟悉一些细节,但是您可以在此处阅读有关 JAX-WS RI / Metro的更多信息。 For CXF 's, you can refer to here , and some examples for Maven's plugin for CXF 's WSDL2Java . 对于CXF ,可以参考这里 ,以及Maven的 CXF WSDL2Java 插件的示例。 Again, every JAX-WS implementation has its own set of tools, but the concepts are identical when it comes to the underlying mapping/binding which is tied to JAXB . 同样,每个JAX-WS实现都有自己的工具集,但是当涉及到与JAXB绑定的基础映射/绑定时,这些概念是相同的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM