そのため、私はmavenを使用maven-jaxb2-plugin
して、大きくて複雑なWSDLファイルからクラスを生成し、この問題に遭遇しました。問題は、WSDLの要素がcomplexType
定義を参照しているtype
ため、要素クラスが生成されておらず、complexTypeクラスを使用しようとすると、欠落した@XmlRootElement
エラーが発生することです。
私の意見では、WSDLを変更することは実際には実行可能な解決策ではありません。実用的な唯一のことは、生成中に欠落している注釈を追加する方法を設計するように思われました。また、リクエストが間違った要素名を送信しており、応答に一致する要素名を持つクラスがなかったため、マーシャリング時にシリアル化で問題が発生しました。
私がやったjaxb2-basics-annotate
ことは、jaxbバインディングファイルを使用して、不足しているアノテーションを必要なクラスに追加できる2番目のMavenプラグインを使用することでした。これにより、不要なコードを追加せずにこの問題を解決する必要がなくなり、将来更新されたWSDLファイルを使用する必要がある場合に簡単に再生成できるようになります。
pom.xml(実行の構成にプラグインセクションがあることに注意してください-WSDLファイルの場所は/src/main/resources/wsdl/EstimatingService.wsdlです)
<project>
...
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<jaxb2.version>0.14.0</jaxb2.version>
<jaxb2.annotate.version>1.1.0</jaxb2.annotate.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>${jaxb2.version}</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-annotate</artifactId>
<version>${jaxb2.annotate.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>${jaxb2.version}</version>
<executions>
<execution>
<id>estimating</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaLanguage>WSDL</schemaLanguage>
<generateDirectory>target/generated-sources/acme/src/gen/estimating-service</generateDirectory>
<generatePackage>com.acme.shipping.estimating.service</generatePackage>
<schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
<schemaIncludes>
<include>EstimatingService.wsdl</include>
</schemaIncludes>
<bindingDirectory>${project.basedir}/src/main/resources/bindings</bindingDirectory>
<bindingIncludes>estimateServiceBinding.xjb</bindingIncludes>
<extension>true</extension>
<args>
<arg>-Xannotate</arg>
<arg>-XremoveAnnotation</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-annotate</artifactId>
</plugin>
</plugins>
</configuration>
</execution>
...
// More executions here if you have multiple WSDL files (Dont forget to give it a different package name and id)
</executions>
</plugin>
</plugins>
</build>
...
</project>
EstimateServiceBinding.xjb(この例で使用されるjaxbバインディングファイル-/src/main/resources/bindings/estimateServiceBinding.xjb )
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:annox="http://annox.dev.java.net" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jaxb:globalBindings generateElementProperty="false">
<xjc:simple />
</jaxb:globalBindings>
<!-- Target the schema section in the WSDL file using the given target namespace which contains the complexType definitions we want to annotate -->
<jaxb:bindings schemaLocation="../wsdl/EstimatingService.wsdl" node="//xs:schema[@targetNamespace='http://acme.com/schema/datatypes/v2']">
<jaxb:bindings node="xs:complexType[@name='GetQuickEstimateRequestContainer']">
<!-- Add the @XmlRootElement annotation to the generated class and then tell it use the correct element name required when marshalling. e.g GetQuickEstimateRequestContainer element is renamed to the element name that referenced it in the WSDL (GetQuickEstimateRequest) -->
<annox:annotateClass>@javax.xml.bind.annotation.XmlRootElement(name="GetQuickEstimateRequest")</annox:annotateClass>
</jaxb:bindings>
<jaxb:bindings node="xs:complexType[@name='GetQuickEstimateResponseContainer']">
<annox:annotateClass>@javax.xml.bind.annotation.XmlRootElement(name="GetQuickEstimateResponse")</annox:annotateClass>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
@XmlRootElementアノテーションと正しい要素名を持つ生成されたクラス(GetQuickEstimateRequestContainer.java)
@XmlRootElement(name = "GetQuickEstimateRequest")
public class GetQuickEstimateRequestContainer {
...
// class member fields & setters and getters
...
}