You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JAXB 4.X.X序列化异常:子类同名字段致父类字段无法序列化

问题原因与解决方案

问题背景

将JAXB从3.0.2升级到4.0.5后,序列化ChildA对象时,父类Parent的ID字段始终无法被序列化。回溯确认问题首次出现在JAXB 4.0.0版本,且仅当ChildB类存在Id字段时触发;移除ChildB的Id字段或回退到JAXB 3.0.2版本,序列化恢复正常。

原因分析

JAXB 4.x版本对属性冲突检测与继承元数据处理逻辑做了变更:

  • JAXB 3.x中,父类Parent的ID字段与子类ChildB的Id字段被视为两个独立XML元素(XML元素名区分大小写),元数据互不干扰。
  • JAXB 4.x中,默认元数据合并逻辑会将大小写不同但名称相似的属性(ID与Id)判定为冲突属性。当ChildB存在时,JAXB会认为子类的Id覆盖了父类的ID,导致整个Parent类的ID字段在序列化时被标记为"已被覆盖",进而影响所有继承自Parent的子类(包括ChildA)的序列化行为。

无需修改WSDL的解决方案

方案1:通过JAXB绑定文件明确字段映射

创建绑定文件bindings.xjb,强制指定每个字段对应的XML元素名,避免冲突检测误判:

<jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               version="3.0">
    <!-- 明确Parent类的ID字段映射 -->
    <jaxb:bindings schemaLocation="test.wsdl" node="//xsd:complexType[@name='Parent']/xsd:sequence/xsd:element[@name='ID']">
        <jaxb:property name="ID"/>
    </jaxb:bindings>
    <!-- 明确ChildB类的Id字段映射 -->
    <jaxb:bindings schemaLocation="test.wsdl" node="//xsd:complexType[@name='ChildB']/xsd:sequence/xsd:element[@name='Id']">
        <jaxb:property name="Id"/>
    </jaxb:bindings>
</jaxb:bindings>

在jaxb-maven-plugin中配置绑定文件:

<plugin>
    <groupId>org.jvnet.jaxb</groupId>
    <artifactId>jaxb-maven-plugin</artifactId>
    <version>4.0.6</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>${jaxb.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <generatePackage>org.example</generatePackage>
        <schemaDirectory>src/main/resources</schemaDirectory>
        <schemaIncludes>
            <include>*.wsdl</include>
        </schemaIncludes>
        <!-- 添加绑定文件配置 -->
        <bindingIncludes>
            <include>bindings.xjb</include>
        </bindingIncludes>
    </configuration>
</plugin>

方案2:配置JAXB上下文的命名策略

创建Jaxb2Marshaller时,设置属性强制使用区分大小写的命名策略:

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("org.example");
// 启用区分大小写的命名策略
Map<String, Object> props = new HashMap<>();
props.put("jakarta.xml.bind.naming.strategy", "org.glassfish.jaxb.runtime.v2.runtime.DefaultNamingStrategy");
marshaller.setMarshallerProperties(props);

该策略会严格区分XML元素名的大小写,避免将ID和Id判定为同一属性。

方案3:通过绑定文件添加自定义注解

若上述方案无效,可通过绑定文件为生成的类添加@XmlElement注解,明确指定XML元素名:

<jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:annox="http://annox.dev.java.net"
               version="3.0">
    <jaxb:bindings schemaLocation="test.wsdl" node="//xsd:complexType[@name='Parent']">
        <annox:annotateClass>
            <annox:annotate annox:class="jakarta.xml.bind.annotation.XmlAccessorType" value="FIELD"/>
        </annox:annotateClass>
        <jaxb:bindings node="//xsd:sequence/xsd:element[@name='ID']">
            <annox:annotateField>
                <annox:annotate annox:class="jakarta.xml.bind.annotation.XmlElement" name="ID"/>
            </annox:annotateField>
        </jaxb:bindings>
    </jaxb:bindings>
    <jaxb:bindings schemaLocation="test.wsdl" node="//xsd:complexType[@name='ChildB']">
        <jaxb:bindings node="//xsd:sequence/xsd:element[@name='Id']">
            <annox:annotateField>
                <annox:annotate annox:class="jakarta.xml.bind.annotation.XmlElement" name="Id"/>
            </annox:annotateField>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

需在jaxb-maven-plugin中添加annox依赖:

<plugin>
    <!-- 其他配置保持不变 -->
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>${jaxb.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jvnet.jaxb2_commons</groupId>
            <artifactId>jaxb2-basics-annotate</artifactId>
            <version>1.1.1</version>
        </dependency>
    </dependencies>
</plugin>

内容的提问来源于stack exchange,提问作者halp_me_plz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 18:19:49