如何配置JAXB/XJC避免重复生成导入的complexType类?
解决XJC重复生成父类的问题
要让父类A仅在org.example包生成,子类B在org.example.child包并导入A类,核心是让XJC识别已生成的类型,避免重复生成。以下是两种可行方案:
方案一:合并处理XSD+绑定文件指定包映射
这种方法通过一次性处理两个XSD,配合绑定文件明确命名空间与包的对应关系,让XJC自动复用已生成的父类。
步骤1:修改XSD添加命名空间
给两个XSD分别指定唯一的targetNamespace,并通过命名空间前缀引用父类:
XSD1.xsd
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.org/a" xmlns:a="http://example.org/a"> <xs:simpleType name="A"> <xs:restriction base="xs:string" /> </xs:simpleType> </xs:schema>
XSD2.xsd
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.org/b" xmlns:b="http://example.org/b" xmlns:a="http://example.org/a"> <xs:import namespace="http://example.org/a" schemaLocation="./XSD1.xsd" /> <xs:simpleType name="B"> <xs:restriction base="a:A" /> </xs:simpleType> </xs:schema>
步骤2:创建绑定文件binding.xml
在src/main/resources下创建绑定文件,指定每个命名空间对应的Java包:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.1"> <jaxb:bindings schemaLocation="XSD1.xsd" node="/xs:schema"> <jaxb:package name="org.example"/> </jaxb:bindings> <jaxb:bindings schemaLocation="XSD2.xsd" node="/xs:schema"> <jaxb:package name="org.example.child"/> </jaxb:bindings> </jaxb:bindings>
步骤3:修改Maven插件配置
将两个XSD放在同一个xsdOption中,引用绑定文件:
<plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-xjc-plugin</artifactId> <version>${cxf.version}</version> <configuration> <extensions> <extension>org.apache.cxf.xjcplugins:cxf-xjc-dv:${cxf.version}</extension> </extensions> </configuration> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <goals> <goal>xsdtojava</goal> </goals> <configuration> <xsdOptions> <xsdOption> <xsd>src/main/resources/XSD1.xsd</xsd> <xsd>src/main/resources/XSD2.xsd</xsd> <bindingFile>src/main/resources/binding.xml</bindingFile> </xsdOption> </xsdOptions> </configuration> </execution> </executions> </plugin>
方案二:分阶段生成+Episode文件复用
这种方法通过先生成父类并导出Episode文件,再在生成子类时引用该文件,告知XJC哪些类已存在。
步骤1:修改Maven插件配置,分两次执行
<plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-xjc-plugin</artifactId> <version>${cxf.version}</version> <configuration> <extensions> <extension>org.apache.cxf.xjcplugins:cxf-xjc-dv:${cxf.version}</extension> </extensions> </configuration> <executions> <!-- 第一步:生成父类A,导出Episode文件 --> <execution> <id>generate-class-a</id> <phase>generate-sources</phase> <goals> <goal>xsdtojava</goal> </goals> <configuration> <xsdOptions> <xsdOption> <xsd>src/main/resources/XSD1.xsd</xsd> <packagename>org.example</packagename> <!-- 生成Episode文件记录已生成的类 --> <episode>target/generated-sources/xjc/META-INF/sun-jaxb.episode</episode> </xsdOption> </xsdOptions> </configuration> </execution> <!-- 第二步:生成子类B,引用Episode文件 --> <execution> <id>generate-class-b</id> <phase>generate-sources</phase> <goals> <goal>xsdtojava</goal> </goals> <configuration> <xsdOptions> <xsdOption> <xsd>src/main/resources/XSD2.xsd</xsd> <packagename>org.example.child</packagename> <!-- 引用Episode文件,避免重复生成A --> <bindingFiles> <bindingFile>target/generated-sources/xjc/META-INF/sun-jaxb.episode</bindingFile> </bindingFiles> </xsdOption> </xsdOptions> </configuration> </execution> </executions> </plugin>
注意事项
- 若采用方案二,建议同样给XSD添加命名空间,避免类型名称冲突导致XJC无法识别已生成的类。
- 确保Episode文件路径正确,Maven会在
target/generated-sources/xjc下自动生成该文件。
内容的提问来源于stack exchange,提问作者tkalvin
相关产品推荐
相关产品推荐

