我在Spring中采用代码优先的方式编写SOAP,但是生成的XSD和WSDL不正确。

huangapple 未分类评论55阅读模式
英文:

My code-first approach for SOAP in spring is not generating the XSDs and WSDL correctly

问题

我已经按照你提供的要求将内容翻译如下:

我已经基本上遵循了这个示例来创建了一个SOAP服务:
https://dzone.com/articles/creating-a-soap-web-service-with-spring-boot-start

但我想采用基于代码的方法(自底向上),所以不是编写XSD并从中生成Java代码,而是编写Java代码并从中生成XSD,如下所示:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>schemagen</id>
            <goals>
                <goal>schemagen</goal>
            </goals>
            <phase>generate-resources</phase>
            <configuration>
                <clearOutputDir>false</clearOutputDir>
                <sources>
                    <source>../soapservice-api/src/main/java/techbasics/soapservice/api/v1</source>
                </sources>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <verbose>true</verbose>
    </configuration>
</plugin>

然后将生成的XSD添加到类路径中,然后用它来生成WSDL。这很好用,但是jaxb2-maven-plugin只会识别使用javax.xml.bind注解(如@XmlElement等)注释的对象,因此只会在XSD文件中生成“模型”对象。

问题是我不知道如何让它区分模型类(生成得很好)和包含操作的端点类:

模型类:

@NoArgsConstructor @AllArgsConstructor @Builder @Data
@XmlType(namespace = SoapService.NAMESPACE_URI_V1)
public class Person {
    @XmlElement(name = "name")
    private String name;

    @XmlElement(name = "age")
    private int age;

    @XmlElementWrapper(name = "qualifications", nillable = true)
    @XmlElement(name = "qualification")
    private List<String> qualifications;
}

服务类:

public class SoapService {
    @PayloadRoot(namespace = "http://localhost:8000/soapService/v1", localPart = "processPerson")
    @ResponsePayload
    public ProcessedPerson processPerson(Person person) {
        // 执行操作
        return return new ProcessedPerson();
    }
}

生成的XSDs:

schema1.xsd:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://localhost:8000/soapService/v1" version="1.0">

  <xs:complexType name="person">
    <xs:sequence>
      <xs:element minOccurs="0" name="name" type="xs:string"/>
      <xs:element name="age" type="xs:int"/>
      <xs:element minOccurs="0" name="qualifications" nillable="true">
        <xs:complexType>
          <xs:sequence>
            <xs:element maxOccurs="unbounded" minOccurs="0" name="qualification" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="processedPerson">
    <xs:sequence>
      <xs:element minOccurs="0" name="name" type="xs:string"/>
      <xs:element name="over18" type="xs:boolean"/>
      <xs:element name="numberOfQualifications" type="xs:int"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

schema2.xsd:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">

  <xs:complexType name="soapService">
    <xs:sequence/>
  </xs:complexType>
</xs:schema>

当然,这将生成一个没有任何操作的WSDL:

此XML文件似乎没有与之相关联的样式信息。文档树如下所示。

<wsdl:definitions
	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	xmlns:sch="http://localhost:8000/soapService/v1"
	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="http://localhost:8000/soapService/v1" targetNamespace="http://localhost:8000/soapService/v1">
	<wsdl:types>
		<xs:schema
			xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://localhost:8000/soapService/v1" version="1.0">
			<xs:complexType name="person">
				<xs:sequence>
					<xs:element minOccurs="0" name="name" type="xs:string"/>
					<xs:element name="age" type="xs:int"/>
					<xs:element minOccurs="0" name="qualifications" nillable="true">
						<xs:complexType>
							<xs:sequence>
								<xs:element maxOccurs="unbounded" minOccurs="0" name="qualification" type="xs:string"/>
							</xs:sequence>
						</xs:complexType>
					</xs:element>
				</xs:sequence>
			</xs:complexType>
			<xs:complexType name="processedPerson">
				<xs:sequence>
					<xs:element minOccurs="0" name="name" type="xs:string"/>
					<xs:element name="over18" type="xs:boolean"/>
					<xs:element name="numberOfQualifications" type="xs:int"/>
				</xs:sequence>
			</xs:complexType>
		</xs:schema>
	</wsdl:types>
	<wsdl:portType name="SoapServiceV1Port"></wsdl:portType>
	<wsdl:binding name="SoapServiceV1PortSoap11" type="tns:SoapServiceV1Port">
		<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
	</wsdl:binding>
	<wsdl:service name="SoapServiceV1PortService">
		<wsdl:port binding="tns:SoapServiceV1PortSoap11" name="SoapServiceV1PortSoap11">
			<soap:address location="http://localhost:8000/soapservice/v1"/>
		</wsdl:port>
	</wsdl:service>
</wsdl:definitions>

如何正确生成XSD(从而生成正确的WSDL)?

英文:

I've created a SOAP service by following this example pretty much to the letter:
https://dzone.com/articles/creating-a-soap-web-service-with-spring-boot-start

But I want to follow a code-first (bottom up) approach so rather than write the xsd and generate the java from it, I write the java and generate the xsd from it like so:

            &lt;plugin&gt;
                &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
                &lt;artifactId&gt;jaxb2-maven-plugin&lt;/artifactId&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;id&gt;schemagen&lt;/id&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;schemagen&lt;/goal&gt;
                        &lt;/goals&gt;
                        &lt;phase&gt;generate-resources&lt;/phase&gt;
                        &lt;configuration&gt;
                            &lt;clearOutputDir&gt;false&lt;/clearOutputDir&gt;
                            &lt;sources&gt;
                                &lt;source&gt;../soapservice-api/src/main/java/techbasics/soapservice/api/v1&lt;/source&gt;
                            &lt;/sources&gt;
                        &lt;/configuration&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
                &lt;configuration&gt;
                    &lt;verbose&gt;true&lt;/verbose&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;

and then add the xsds to the classpath, which is then used to generate the wsdl. This works great except that the jaxb2-maven-plugin only picks up the objects annotated with java.xml.bind annotations like @XmlElement and so on, and so only generates "model" objects in the xsd files.

The problem is I don't know how to make it distinguish between model classes (which are generated fine) and the endpoint class containing the operations:

Model class:

@NoArgsConstructor @AllArgsConstructor @Builder @Data
@XmlType(namespace = SoapService.NAMESPACE_URI_V1)
public class Person {
	@XmlElement(name = &quot;name&quot;)
	private String name;

	@XmlElement(name = &quot;age&quot;)
	private int age;

	@XmlElementWrapper(name = &quot;qualifications&quot;, nillable = true)
	@XmlElement(name = &quot;qualification&quot;)
	private List&lt;String&gt; qualifications;
}

Service class:

public class SoapService {
    @PayloadRoot(namespace = &quot;http://localhost:8000/soapService/v1&quot;, localPart = &quot;processPerson&quot;)
    @ResponsePayload
    public ProcessedPerson processPerson(Person person) {
        //do stuff
        return return new ProcessedPerson();
    }
}

Generated XSDs:

schema1.xsd:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;xs:schema xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot; targetNamespace=&quot;http://localhost:8000/soapService/v1&quot; version=&quot;1.0&quot;&gt;

  &lt;xs:complexType name=&quot;person&quot;&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element minOccurs=&quot;0&quot; name=&quot;name&quot; type=&quot;xs:string&quot;/&gt;
      &lt;xs:element name=&quot;age&quot; type=&quot;xs:int&quot;/&gt;
      &lt;xs:element minOccurs=&quot;0&quot; name=&quot;qualifications&quot; nillable=&quot;true&quot;&gt;
        &lt;xs:complexType&gt;
          &lt;xs:sequence&gt;
            &lt;xs:element maxOccurs=&quot;unbounded&quot; minOccurs=&quot;0&quot; name=&quot;qualification&quot; type=&quot;xs:string&quot;/&gt;
          &lt;/xs:sequence&gt;
        &lt;/xs:complexType&gt;
      &lt;/xs:element&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;

  &lt;xs:complexType name=&quot;processedPerson&quot;&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element minOccurs=&quot;0&quot; name=&quot;name&quot; type=&quot;xs:string&quot;/&gt;
      &lt;xs:element name=&quot;over18&quot; type=&quot;xs:boolean&quot;/&gt;
      &lt;xs:element name=&quot;numberOfQualifications&quot; type=&quot;xs:int&quot;/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;

schema2.xsd:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;xs:schema xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot; version=&quot;1.0&quot;&gt;

  &lt;xs:complexType name=&quot;soapService&quot;&gt;
    &lt;xs:sequence/&gt;
  &lt;/xs:complexType&gt;
&lt;/xs:schema&gt;

Of course this generates a wsdl without any operations:

This XML file does not appear to have any style information associated with it. The document tree is shown below.

&lt;wsdl:definitions
	xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot;
	xmlns:sch=&quot;http://localhost:8000/soapService/v1&quot;
	xmlns:soap=&quot;http://schemas.xmlsoap.org/wsdl/soap/&quot;
	xmlns:tns=&quot;http://localhost:8000/soapService/v1&quot; targetNamespace=&quot;http://localhost:8000/soapService/v1&quot;&gt;
	&lt;wsdl:types&gt;
		&lt;xs:schema
			xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot; targetNamespace=&quot;http://localhost:8000/soapService/v1&quot; version=&quot;1.0&quot;&gt;
			&lt;xs:complexType name=&quot;person&quot;&gt;
				&lt;xs:sequence&gt;
					&lt;xs:element minOccurs=&quot;0&quot; name=&quot;name&quot; type=&quot;xs:string&quot;/&gt;
					&lt;xs:element name=&quot;age&quot; type=&quot;xs:int&quot;/&gt;
					&lt;xs:element minOccurs=&quot;0&quot; name=&quot;qualifications&quot; nillable=&quot;true&quot;&gt;
						&lt;xs:complexType&gt;
							&lt;xs:sequence&gt;
								&lt;xs:element maxOccurs=&quot;unbounded&quot; minOccurs=&quot;0&quot; name=&quot;qualification&quot; type=&quot;xs:string&quot;/&gt;
							&lt;/xs:sequence&gt;
						&lt;/xs:complexType&gt;
					&lt;/xs:element&gt;
				&lt;/xs:sequence&gt;
			&lt;/xs:complexType&gt;
			&lt;xs:complexType name=&quot;processedPerson&quot;&gt;
				&lt;xs:sequence&gt;
					&lt;xs:element minOccurs=&quot;0&quot; name=&quot;name&quot; type=&quot;xs:string&quot;/&gt;
					&lt;xs:element name=&quot;over18&quot; type=&quot;xs:boolean&quot;/&gt;
					&lt;xs:element name=&quot;numberOfQualifications&quot; type=&quot;xs:int&quot;/&gt;
				&lt;/xs:sequence&gt;
			&lt;/xs:complexType&gt;
		&lt;/xs:schema&gt;
	&lt;/wsdl:types&gt;
	&lt;wsdl:portType name=&quot;SoapServiceV1Port&quot;&gt;&lt;/wsdl:portType&gt;
	&lt;wsdl:binding name=&quot;SoapServiceV1PortSoap11&quot; type=&quot;tns:SoapServiceV1Port&quot;&gt;
		&lt;soap:binding style=&quot;document&quot; transport=&quot;http://schemas.xmlsoap.org/soap/http&quot;/&gt;
	&lt;/wsdl:binding&gt;
	&lt;wsdl:service name=&quot;SoapServiceV1PortService&quot;&gt;
		&lt;wsdl:port binding=&quot;tns:SoapServiceV1PortSoap11&quot; name=&quot;SoapServiceV1PortSoap11&quot;&gt;
			&lt;soap:address location=&quot;http://localhost:8000/soapservice/v1&quot;/&gt;
		&lt;/wsdl:port&gt;
	&lt;/wsdl:service&gt;
&lt;/wsdl:definitions&gt;

How can I generate the XSDs (and therefore the wsdl) correctly?

huangapple
  • 本文由 发表于 2020年5月4日 03:09:50
  • 转载请务必保留本文链接:https://java.coder-hub.com/61580184.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定