肥皂响应无法正确解析

时间:2017-12-05 10:28:34

标签: java spring-boot soap wsdl

我想使用spring-boot从wsdl url中提取响应数据。我遵循本教程:https://spring.io/guides/gs/consuming-web-service/。我试过了,它已成功运行。

我的配置:

@Configuration
public class MyConfiguration {

  @Bean
  public Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();

    marshaller.setContextPath("com.mypackage");
    return marshaller;
  }

  @Bean
  public MyClient myClient(Jaxb2Marshaller marshaller) {
    MyClient client = new MyClient();
    client.setDefaultUri("http://example.com/v1/report.asmx?WSDL");
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);
    return client;
  }
}

我的客户:

public class MyClient extends WebServiceGatewaySupport {

  public MyEndpointResponse getResponse() {

    MyEndpoint request = new MyEndpoint();
    request.setUsername("...");
    ...

    MyEndpointResponse response = (MyEndpointResponse) getWebServiceTemplate()
            .marshalSendAndReceive("http://example.com/v1/report.asmx?WSDL",
                    request,
                    new SoapActionCallback("http:/example.com/MyEndpoint"));

    return response;
}

我的pom.xml:

<dependencies>
    ...
    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core</artifactId>
    </dependency>
    ...
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>           
        <!-- tag::wsdl[] -->
        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.12.3</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <schemaLanguage>WSDL</schemaLanguage>
                <generatePackage>com.mypackage.wsdl</generatePackage>                   
                <schemas>
                    <schema>
                        <url>http:/example.com/v1/report.asmx?WSDL</url>
                    </schema>
                </schemas>
            </configuration>
        </plugin>
        <!-- end::wsdl[] -->
    </plugins>
</build>

我的wsdl文件看起来像这样:

<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.Foo.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.Foo.com/">
<wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://example.com/">
        <s:element name="MyEndpoint">
            <s:complexType>
                <s:sequence>
                    <s:element minOccurs="0" maxOccurs="1" name="Username" type="s:string"/>
                </s:sequence>
            </s:complexType>
        </s:element>
        <s:element name="MyEndpointResponse">
            <s:complexType>
                <s:sequence>
                    <s:element minOccurs="0" maxOccurs="1" name="MyEndpointResult">
                        <s:complexType>
                            <s:sequence>
                                <s:element ref="s:schema"/>
                                <s:any/>
                            </s:sequence>
                        </s:complexType>
                    </s:element>
                </s:sequence>
            </s:complexType>
        </s:element>
        ...
        <s:element name="string" nillable="true" type="s:string"/>
        <s:element name="DataSet" nillable="true">
            <s:complexType>
                <s:sequence>
                    <s:element ref="s:schema"/>
                    <s:any/>
                </s:sequence>
            </s:complexType>
        </s:element>
        <s:element name="ArrayOfLastPacket" nillable="true" type="tns:ArrayOfLastPacket"/>
    </s:schema>
</wsdl:types>
<wsdl:message name="MyEndpointSoapIn">
    <wsdl:part name="parameters" element="tns:MyEndpoint"/>
</wsdl:message>
<wsdl:message name="MyEndpointSoapOut">
    <wsdl:part name="parameters" element="tns:MyEndpointResponse"/>
</wsdl:message>
<wsdl:message name="MyEndpointHttpGetIn">
    <wsdl:part name="Username" type="s:string"/>
    <wsdl:part name="PIN1" type="s:string"/>
    <wsdl:part name="PIN2" type="s:string"/>
    <wsdl:part name="Language" type="s:string"/>
</wsdl:message>
<wsdl:message name="MyEndpointHttpGetOut">
    <wsdl:part name="Body" element="tns:DataSet"/>
</wsdl:message>
<wsdl:portType name="Foo_x0020_Report_x0020_Web_x0020_ServiceSoap">
    <wsdl:operation name="MyEndpoint">
        <wsdl:input message="tns:MyEndpointSoapIn"/>
        <wsdl:output message="tns:MyEndpointSoapOut"/>
    </wsdl:operation>
</wsdl:portType>
<wsdl:portType name="Foo_x0020_Report_x0020_Web_x0020_ServiceHttpGet">
    <wsdl:operation name="MyEndpoint">
        <wsdl:input message="tns:MyEndpointHttpGetIn"/>
        <wsdl:output message="tns:MyEndpointHttpGetOut"/>
    </wsdl:operation>
</wsdl:portType>
<wsdl:portType name="Foo_x0020_Report_x0020_Web_x0020_ServiceHttpPost">
    <wsdl:operation name="MyEndpoint">
        <wsdl:input message="tns:MyEndpointHttpPostIn"/>
        <wsdl:output message="tns:MyEndpointHttpPostOut"/>
    </wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Foo_x0020_Report_x0020_Web_x0020_ServiceSoap" type="tns:Foo_x0020_Report_x0020_Web_x0020_ServiceSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="MyEndpoint">
        <soap:operation soapAction="http://www.Foo.com/MyEndpoint" style="document"/>
        <wsdl:input>
            <soap:body use="literal"/>
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal"/>
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>
<wsdl:binding name="Foo_x0020_Report_x0020_Web_x0020_ServiceSoap12" type="tns:Foo_x0020_Report_x0020_Web_x0020_ServiceSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="MyEndpoint">
        <soap12:operation soapAction="http://www.Foo.com/MyEndpoint" style="document"/>
        <wsdl:input>
            <soap12:body use="literal"/>
        </wsdl:input>
        <wsdl:output>
            <soap12:body use="literal"/>
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>
<wsdl:binding name="Foo_x0020_Report_x0020_Web_x0020_ServiceHttpGet" type="tns:Foo_x0020_Report_x0020_Web_x0020_ServiceHttpGet">
    <http:binding verb="GET"/>
    <wsdl:operation name="MyEndpoint">
        <http:operation location="/MyEndpoint"/>
        <wsdl:input>
            <http:urlEncoded/>
        </wsdl:input>
        <wsdl:output>
            <mime:mimeXml part="Body"/>
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>
<wsdl:binding name="Foo_x0020_Report_x0020_Web_x0020_ServiceHttpPost" type="tns:Foo_x0020_Report_x0020_Web_x0020_ServiceHttpPost">
    <http:binding verb="POST"/>
    <wsdl:operation name="MyEndpoint">
        <http:operation location="/MyEndpoint"/>
        <wsdl:input>
            <mime:content type="application/x-www-form-urlencoded"/>
        </wsdl:input>
        <wsdl:output>
            <mime:mimeXml part="Body"/>
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>
<wsdl:service name="Foo_x0020_Report_x0020_Web_x0020_Service">
    <wsdl:port name="Foo_x0020_Report_x0020_Web_x0020_ServiceSoap" binding="tns:Foo_x0020_Report_x0020_Web_x0020_ServiceSoap">
        <soap:address location="http://example.com/v1/report.asmx"/>
    </wsdl:port>
    <wsdl:port name="Foo_x0020_Report_x0020_Web_x0020_ServiceSoap12" binding="tns:Foo_x0020_Report_x0020_Web_x0020_ServiceSoap12">
        <soap12:address location="http://example.com/v1/report.asmx"/>
    </wsdl:port>
    <wsdl:port name="Foo_x0020_Report_x0020_Web_x0020_ServiceHttpGet" binding="tns:Foo_x0020_Report_x0020_Web_x0020_ServiceHttpGet">
        <http:address location="http://example.com/v1/report.asmx"/>
    </wsdl:port>
    <wsdl:port name="Foo_x0020_Report_x0020_Web_x0020_ServiceHttpPost" binding="tns:Foo_x0020_Report_x0020_Web_x0020_ServiceHttpPost">
        <http:address location="http://example.com/v1/report.asmx"/>
    </wsdl:port>
</wsdl:service>

1- 我的第一个问题: 使用maven构建时出现错误,如下所示:

[INFO] Sources are not up-to-date, XJC will be executed.
[ERROR] Error while parsing schema(s).Location [ http://example.com/v1/report.asmx?WSDL{37,47}].
org.xml.sax.SAXParseException; systemId: http://example.com/v1/report.asmx?WSDL; lineNumber: 37; columnNumber: 47; undefined element declaration 's:schema'
    at com.sun.xml.xsom.impl.parser.ParserContext$1.reportError(ParserContext.java:180)
    at com.sun.xml.xsom.impl.parser.NGCCRuntimeEx.reportError(NGCCRuntimeEx.java:175)
    at com.sun.xml.xsom.impl.parser.DelayedRef.resolve(DelayedRef.java:110)
    at com.sun.xml.xsom.impl.parser.DelayedRef.run(DelayedRef.java:85)
    at com.sun.xml.xsom.impl.parser.ParserContext.getResult(ParserContext.java:135)
    at com.sun.xml.xsom.parser.XSOMParser.getResult(XSOMParser.java:214)
    at com.sun.tools.xjc.ModelLoader.loadWSDL(ModelLoader.java:412)
    at com.sun.tools.xjc.ModelLoader.load(ModelLoader.java:170)
    at com.sun.tools.xjc.ModelLoader.load(ModelLoader.java:119)
    at org.jvnet.mjiip.v_2_2.XJC22Mojo.loadModel(XJC22Mojo.java:50)
    at org.jvnet.mjiip.v_2_2.XJC22Mojo.doExecute(XJC22Mojo.java:40)
    at org.jvnet.mjiip.v_2_2.XJC22Mojo.doExecute(XJC22Mojo.java:28)
    at org.jvnet.jaxb2.maven2.RawXJC2Mojo.doExecute(RawXJC2Mojo.java:488)
    at org.jvnet.jaxb2.maven2.RawXJC2Mojo.execute(RawXJC2Mojo.java:311)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
[ERROR] Error while parsing schema(s).Location [ http://example.com/v1/report.asmx?WSDL{60,47}].
org.xml.sax.SAXParseException; systemId: http://example.com/v1/report.asmx?WSDL; lineNumber: 60; columnNumber: 47; undefined element declaration 's:schema'
...
...

如果我将xsd架构(&#34; http://www.w3.org/2001/XMLSchema.xsd&#34;)添加到pom.xml中的插件,我的第一个问题就解决了。 这样正确吗?

<plugin>
    ...
    <configuration>
        ...
        <schemas>
            //newly added part begin 
            <schema>
                <url>http://www.w3.org/2001/XMLSchema.xsd</url>
            </schema>
            //newly added part end

            <schema>
                <url>http://example.com/v1/report.asmx?WSDL</url>
            </schema>
        </schemas>
    </configuration>
</plugin>

2- 解决第一个问题后出现的新问题:

我的代码使用maven成功构建,并使用wsdl的maven插件生成一些类。然后我运行我的代码,我没有看到正确的回应。我的回答如下:

enter image description here

由org.jvnet.jaxb2.maven2插件生成的类(当使用** wsimport **命令时也会生成相同的类):

// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2017.12.05 at 12:36:10 PM MSK 
//

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;element name="MyEndointResult" minOccurs="0"&gt;
 *           &lt;complexType&gt;
 *             &lt;complexContent&gt;
 *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *                 &lt;sequence&gt;
 *                   &lt;element ref="{http://www.w3.org/2001/XMLSchema}schema"/&gt;
 *                   &lt;any/&gt;
 *                 &lt;/sequence&gt;
 *               &lt;/restriction&gt;
 *             &lt;/complexContent&gt;
 *           &lt;/complexType&gt;
 *         &lt;/element&gt;
 *       &lt;/sequence&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "myEndpointResult"
})
@XmlRootElement(name = "MyEndpointResponse")
public class MyEndpointResponse {

    @XmlElement(name = "MyEndpointResult")
    protected MyEndpointResponse.MyEndpointResult myEndpointResult;

    /**
     * Gets the value of the myEndpointResult property.
     * 
     * @return
     *     possible object is
     *     {@link MyEndpointResponse.MyEndpointResult }
     *     
     */
    public MyEndpointResponse.MyEndpointResult myEndpointResult() {
        return getVehicleStatusResult;
    }

    /**
     * Sets the value of the myEndpointResult property.
     * 
     * @param value
     *     allowed object is
     *     {@link myEndpointResponse.MyEndpointResult }
     *     
     */
    public void setMyEndpointResult(MyEndpointResponse.MyEndpointResult value) {
        this.myEndpointResult = value;
    }


    /**
     * <p>Java class for anonymous complex type.
     * 
     * <p>The following schema fragment specifies the expected content contained within this class.
     * 
     * <pre>
     * &lt;complexType&gt;
     *   &lt;complexContent&gt;
     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
     *       &lt;sequence&gt;
     *         &lt;element ref="{http://www.w3.org/2001/XMLSchema}schema"/&gt;
     *         &lt;any/&gt;
     *       &lt;/sequence&gt;
     *     &lt;/restriction&gt;
     *   &lt;/complexContent&gt;
     * &lt;/complexType&gt;
     * </pre>
     * 
     * 
     */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "schema",
        "any"
    })
    public static class MyEndpointResult {

        @XmlElement(namespace = "http://www.w3.org/2001/XMLSchema", required = true)
        protected Schema schema;
        @XmlAnyElement(lax = true)
        protected Object any;

        /**
         * Gets the value of the schema property.
         * 
         * @return
         *     possible object is
         *     {@link Schema }
         *     
         */
        public Schema getSchema() {
            return schema;
        }

        /**
         * Sets the value of the schema property.
         * 
         * @param value
         *     allowed object is
         *     {@link Schema }
         *     
         */
        public void setSchema(Schema value) {
            this.schema = value;
        }

        /**
         * Gets the value of the any property.
         * 
         * @return
         *     possible object is
         *     {@link Object }
         *     
         */
        public Object getAny() {
            return any;
        }

        /**
         * Sets the value of the any property.
         * 
         * @param value
         *     allowed object is
         *     {@link Object }
         *     
         */
        public void setAny(Object value) {
            this.any = value;
        }

    }

}

如何解析xml?

0 个答案:

没有答案