英文:
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:
<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>
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 = "name")
private String name;
@XmlElement(name = "age")
private int age;
@XmlElementWrapper(name = "qualifications", nillable = true)
@XmlElement(name = "qualification")
private List<String> qualifications;
}
Service class:
public class SoapService {
@PayloadRoot(namespace = "http://localhost:8000/soapService/v1", localPart = "processPerson")
@ResponsePayload
public ProcessedPerson processPerson(Person person) {
//do stuff
return return new ProcessedPerson();
}
}
Generated 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>
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>
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.
<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>
How can I generate the XSDs (and therefore the wsdl) correctly?
专注分享java语言的经验与见解,让所有开发者获益!
评论