简体   繁体   English

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

[英]Spring Soap web service client using a WSDL and codehaus jaxb2; need XmlRootElement?

I am working within an existing Spring web application; 我正在现有的Spring Web应用程序中工作; I need to write code to call to a SOAP web service that provides a WSDL. 我需要编写代码来调用提供WSDL的SOAP Web服务。 I also use Netbeans, though am willing to jump out to a command line whenever that's easier. 我也使用Netbeans,尽管只要愿意,我愿意跳到命令行。

I have configured the Maven pom for the project to include the codehaus jaxb2-maven-plugin, and written a small test program to send a request. 我已经为该项目配置了Maven pom,使其包括codehaus jaxb2-maven-plugin,并编写了一个小的测试程序来发送请求。 When that call is executed, I get an error saying that it cannot process one of the generated classes because it has no XmlRootElement annotation. 执行该调用时,我收到一条错误消息,指出它无法处理生成的类之一,因为它没有XmlRootElement批注。

On searching further for that error, I find LOTS of requests for information on it, but none that apply. 在进一步搜索该错误时,我发现有很多请求提供有关此错误的信息,但没有一个适用。 Most of them use a different JaxB library, and all of them give me examples of how to configure their plugin, not the one I have. 他们中的大多数人使用不同的JaxB库,并且所有人都为我提供了有关如何配置其插件的示例,而不是我所拥有的示例。

I suppose I can change plugins (I already have once), but what I would REALLY like is to find some decent documentation on THIS one. 我想我可以更改插件(我已经有过一次),但是我真正想要的是在此插件上找到一些不错的文档。 I need something that can be done on Java 7, not 8, that does not involve Spring 4 (or 5, or 6), preferably just an explanation of the various options that can be supplied to the maven plugin and/or the command line to generate classes so they can be marshalled and unmarshalled by Spring's default classes for the purposes. 我需要可以在Java 7而不是8上完成的工作,而不涉及Spring 4(或5或6),最好只是对可以提供给Maven插件和/或命令行的各种选项进行说明。生成类,以便为此目的可以使用Spring的默认类对它们进行编组和解组。

--- Edit -编辑

Here's what I have at the moment; 这是我目前的状况; since it's testing code, I just have the marshaller declared and set up in the code instead of the configuration: 因为它是测试代码,所以我只在代码中声明并设置了编组器,而不是在配置中进行了设置:

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

}

When I run my program, it gives the following (just first lines): 当我运行程序时,它给出以下内容(仅第一行):

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)

I put in the line about preferring Spring libraries since a lot of answers on SO seem to take the form of "Change over to this tool/library", not because I didn't think it could be done in Spring. 我倾向于使用Spring库,因为关于SO的许多答案似乎都采取“切换到该工具/库”的形式,并不是因为我不认为可以在Spring中完成。 I'll be happy to configure and use a marshaller within Spring, as soon as I figure out (or am told) how. 一弄清(或被告知)如何,我将很乐意在Spring中配置和使用编组器。

I finally got this working; 我终于开始工作了; it does seem like it ought to be easier. 似乎确实应该更容易。

The POM file entry for the JAXB Maven plugin now looks like this: 现在,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>

One of the difficulties I faced was a lack of documentation on the options here; 我面临的困难之一是此处没有关于这些选项的文档。 I eventually looked inside the jar file in the plugin code and found the jaxb2-maven-plugin.pom there, and looked through the unformatted documentation for the various options. 我最终查看了插件代码中的jar文件,并在其中找到了jaxb2-maven-plugin.pom,并浏览了未格式化的文档以了解各种选项。 This is how I discovered the "sourceType", "sources", and "xjbSources" tags. 这就是我发现“ sourceType”,“ sources”和“ xjbSources”标签的方式。 It was also looking in that part of my .m2 directory that helped me realize the different versions available, and the docs available on the web do warn you of the major differences between 1.x and 2.x. 它也在.m2目录的该部分中查找,该部分帮助我实现了可用的不同版本,并且Web上的可用文档确实警告您1.x和2.x之间的主要差异。

Anyway, I had found the following bindings file, though wasn't sure until later how to specify a bindings file in this version of the plugin: 无论如何,我已经找到了以下绑定文件,尽管直到后来不确定如何在此版本的插件中指定绑定文件:

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

The specification of in the bindings is what causes the @XmlRootElement in the generated sources; 绑定中的规范是导致@XmlRootElement生成的源中的原因。 you need this if your WSDL has complex types that have a defined name. 如果您的WSDL具有定义了名称的复杂类型,则需要此功能。

Then my client boiled down to this: 然后我的客户归结为:

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

In the final Spring application, I would be more likely to configure the marshaller URI and bound classes instead of writing code to set them, but to use in my little testing program this was easier. 在最终的Spring应用程序中,我将更有可能配置marshaller URI和绑定类,而不是编写用于设置它们的代码,但是在我的小型测试程序中使用起来会更容易。

So this allows me to build up my pricingRequest object and get back a GetPricingResponse object, and use any of the other API methods similarly. 因此,这使我可以建立自己的priceingRequest对象,并获取GetPricingResponse对象,并类似地使用任何其他API方法。

Hope this is a help to someone else. 希望这对其他人有帮助。

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

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