Spring Soap Web服务客户端使用WSDL和codehaus jaxb2;需要XmlRootElement?

时间:2016-05-11 23:35:26

标签: java spring maven soap wsdl

我在现有的Spring Web应用程序中工作;我需要编写代码来调用提供WSDL的SOAP Web服务。我也使用Netbeans,但只要更容易就跳出命令行。

我已经为项目配置了Maven pom,以包含codehaus jaxb2-maven-plugin,并编写了一个小测试程序来发送请求。执行该调用时,我收到一条错误消息,指出它无法处理其中一个生成的类,因为它没有XmlRootElement注释。

在进一步搜索该错误时,我发现了很多关于它的信息请求,但没有一个适用。他们中的大多数使用不同的JaxB库,所有这些都给我提供了如何配置插件的示例,而不是我的插件。

我想我可以更换插件(我已经有了一次),但我真正喜欢的是在这个上找到一些体面的文档。我需要的东西可以在Java 7上完成,而不是8,不涉及Spring 4(或5或6),最好只是解释可以提供给maven插件和/或命令行的各种选项生成类,以便它们可以被Spring的默认类编组和解组。

---编辑

这是我现在所拥有的;因为它测试代码,我只是在代码中声明并设置了编组器,而不是配置:

public class XClient extends WebServiceGatewaySupport {
    public GetXResponse getXResponse(GetX XRequest) {
        // do in configuration for production...
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("com.X.pics.service");
        setMarshaller(marshaller);
        setUnmarshaller(marshaller);

        String uri = "https://site.X.com/services/X";
        WebServiceTemplate template = getWebServiceTemplate();
        Object response = template.marshalSendAndReceive(uri,
                                                         XRequest
                                                         );
        GetXResponse getXResponse = (GetXResponse) response;
        return getXResponse;
    }

}

当我运行我的程序时,它提供以下内容(只是第一行):

org.springframework.oxm.MarshallingFailureException: JAXB marshalling exception; nested exception is javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "com.xo.pics.service.GetPricing" as an element because it is missing an @XmlRootElement annotation]
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:237)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:322)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:483)

我提出了更喜欢Spring库的问题,因为很多关于SO的答案似乎采取了#34;转换到这个工具/库"的形式,不是因为我没有想到它可以在春天完成。一旦我弄清楚(或被告知)如何,我很乐意在Spring中配置和使用marshaller。

1 个答案:

答案 0 :(得分:2)

我终于有了这个工作;它似乎应该更容易。

JAXB Maven插件的POM文件条目现在如下所示:

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>jaxb2-maven-plugin</artifactId>
          <version>2.2</version>
          <executions>
              <execution>
                  <id>xjc</id>
                  <goals>
                      <goal>xjc</goal>
                  </goals>
              </execution>
          </executions>
          <configuration>
              <sourceType>wsdl</sourceType>
              <sources>
                  <source>C:/projects/gw/src/main/resources/wsdl/xo2.wsdl</source>
              </sources>
              <extension>true</extension>
              <xjbSources>
                  <xjbSource>bindings.xjb</xjbSource>
              </xjbSources>
          </configuration>
        </plugin>

我遇到的困难之一是缺乏有关选项的文件;我最终查看了插件代码中的jar文件,并在那里找到了jaxb2-maven-plugin.pom,并查看了无格式文档中的各种选项。这就是我发现&#34; sourceType&#34;,&#34;来源&#34;和&#34; xjbSources&#34;标签。它也在查看我的.m2目录的那一部分,它帮助我实现了可用的不同版本,并且网上提供的文档确实警告你1.x和2.x之间的主要区别。

无论如何,我找到了以下绑定文件,但直到后来才知道如何在此版本的插件中指定绑定文件:

<?xml version="1.0"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc"
              jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jxb:bindings>
        <jxb:globalBindings>
            <xjc:simple/>
        </jxb:globalBindings>
    </jxb:bindings>
</jxb:bindings>

绑定中的规范是导致生成的源中@XmlRootElement的原因;如果您的WSDL具有定义名称的复杂类型,则需要这样做。

然后我的客户归结为:

public class XOClient extends WebServiceGatewaySupport {
    public GetPricingResponse getPricingResponse(GetPricing pricingRequest) {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setClassesToBeBound(GetPricing.class, GetPricingResponse.class);
        setMarshaller(marshaller);
        setUnmarshaller(marshaller);


        String uri = "https://blah.blah.blah.com/services/pricing";
        Object o = getWebServiceTemplate().marshalSendAndReceive(uri, pricingRequest);
        GetPricingResponse response = (GetPricingResponse)o;
        return response;
    }
}

在最终的Spring应用程序中,我更有可能配置marshaller URI和绑定类,而不是编写代码来设置它们,但是在我的小测试程序中使用它更容易。

因此,这允许我构建我的pricingRequest对象并获取GetPricingResponse对象,并类似地使用任何其他API方法。

希望这对别人有帮助。