JAXB2-XJC生成类中@XmlElement.type属性异常问题求助
问题解决:XSD生成Java类时@XmlElement的
type = Object.class导致反序列化失败 问题核心
从XSD生成MainObject类时,SubObject字段的@XmlElement注解被自动添加了type = Object.class属性,导致XML反序列化时,SubObject节点被解析为ElementNSImpl对象,无法赋值给SubObject类型的字段。手动移除该属性后反序列化恢复正常,需要解决生成阶段的配置问题,避免生成这个多余的type属性。
解决方案
方案1:修正XJB绑定文件(适配JAXB 3.x/CXF 4.x)
新版本插件的绑定逻辑和旧版(JAXB 2.x/CXF 2.x)存在差异,原绑定方式未正确覆盖默认类型推断。调整绑定文件的XPath定位,并确保先加载SubObject的XSD:
<?xml version="1.0" encoding="UTF-8"?> <jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="3.0"> <!-- 先绑定subobject.xsd,确保SubObject类优先生成 --> <jaxb:bindings schemaLocation="../xsd/subobject.xsd" version="1.0"> <jaxb:schemaBindings> <jaxb:package name="org.acme.generated"/> </jaxb:schemaBindings> </jaxb:bindings> <!-- 精准定位MainObject内部的SubObject元素,绑定到已生成的SubObject类 --> <jaxb:bindings schemaLocation="../xsd/mainobject.xsd" version="1.0"> <jaxb:bindings node="//xsd:complexType[@name='MainObject']//xsd:element[@name='SubObject']"> <jaxb:class ref="org.acme.generated.SubObject"/> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
方案2:调整Maven插件的XSD处理顺序
不管使用jaxb2-maven-plugin还是cxf-xjc-plugin,都要确保subobject.xsd先被处理,让插件先生成SubObject类,再处理mainobject.xsd:
以cxf-xjc-plugin v4.0.0为例:
<plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-xjc-plugin</artifactId> <version>4.0.0</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <goals> <goal>xsdtojava</goal> </goals> <configuration> <sourceRoot>${project.build.directory}/generated-sources</sourceRoot> <xsdOptions> <!-- 优先处理subobject.xsd --> <xsdOption> <xsd>src/main/resources/xsd/subobject.xsd</xsd> <packagename>org.acme.generated</packagename> </xsdOption> <!-- 再处理mainobject.xsd并绑定配置 --> <xsdOption> <xsd>src/main/resources/xsd/mainobject.xsd</xsd> <packagename>org.acme.generated</packagename> <bindingFile>src/main/resources/xjb/bindings.xjb</bindingFile> </xsdOption> </xsdOptions> </configuration> </execution> </executions> </plugin>
方案3:使用XJC扩展插件强制指定type属性
如果前两种方法无效,可借助jaxb2-basics扩展插件,强制将type属性设置为SubObject.class:
- 先在Maven插件中引入扩展依赖:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>3.1.0</version> <dependencies> <dependency> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics</artifactId> <version>1.11.1</version> </dependency> </dependencies> <configuration> <sources>src/main/resources/xsd</sources> <outputDirectory>src/main/generated</outputDirectory> <xjbSources> <xjbSource>src/main/resources/xjb/bindings.xjb</xjbSource> </xjbSources> <packageName>org.acme.generated</packageName> <extension>true</extension> </configuration> </plugin>
- 修改XJB绑定文件,添加注解强制指定类型:
<?xml version="1.0" encoding="UTF-8"?> <jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jaxb2="http://jaxb2-commons.dev.java.net/basic" jaxb:extensionBindingPrefixes="jaxb2" version="3.0"> <jaxb:bindings schemaLocation="../xsd/mainobject.xsd" version="1.0"> <jaxb:bindings node="//xsd:complexType[@name='MainObject']//xsd:element[@name='SubObject']"> <jaxb2:annotate> <jaxb2:annox>@javax.xml.bind.annotation.XmlElement(type=org.acme.generated.SubObject.class)</jaxb2:annox> </jaxb2:annotate> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
验证效果
生成后的MainObject类中,SubObject字段的@XmlElement注解应变为:
@XmlElement(name = "SubObject", required = true) protected SubObject subObject;
或明确指定type=SubObject.class,两种情况都能正常完成XML反序列化。
内容的提问来源于stack exchange,提问作者Cps
相关产品推荐
相关产品推荐

