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

如何禁用MOXy DynamicJAXBContext的href展开功能?

禁用MOXy Dynamic JAXB的IDREF自动解析,保留原始href值

问题背景

我正把业务流程从XML->StaticJAXB->MongoDocument迁移到XML->DynamicJAXB->MongoDocument,核心实现代码如下:

DynamicJAXBContext dynamicContext = DynamicJAXBContextFactory.createContextFromXSD(xmlSchema, entityResolver, classLoader, properties);
JAXBUnmarshaller unmarshaller = dynamicContext.createUnmarshaller();
JAXBElement root = (JAXBElement) unmarshaller.unmarshal(xml);

对应的XML Schema片段:

<xsd:complexType name="ContactReference">
    <xsd:attribute name="href" type="xsd:IDREF" use="required">
        <xsd:annotation>
            <xsd:documentation>A reference to the @id value of contact/NamedPerson detailed elsewhere in this document.</xsd:documentation>
        </xsd:annotation>
    </xsd:attribute>
</xsd:complexType>

入站XML示例:

<clientContact>
    <accountOfficer id="_1_39" type="RelationshipManager">
        <identifier name="Name">Robin Roos</identifier>
        <emailAddress>robin.roos@test.com</emailAddress>
    </accountOfficer>
    <primaryAccountOfficer href="_1_39"/>
</clientContact>

目前MOXy会自动把href属性解析为对应的accountOfficer实体实例,生成的JSON包含展开后的实体内容。但我需要禁用这种IDREF自动解析,直接保留原始的href字符串值,而非解析后的实体。现在只能手动遍历替换DynamicElement的href值临时解决,希望通过MOXy的配置开关实现,避免硬编码依赖属性名称。

解决方案

可以通过自定义IDResolver来控制MOXy对IDREF的解析行为,无需依赖属性名:

方式1:创建DynamicJAXBContext时传入自定义属性

初始化DynamicJAXBContext时,添加org.eclipse.persistence.jaxb.IDRESOLVER属性,传入一个直接返回原始ID的IDResolver实现:

Map<String, Object> properties = new HashMap<>();
properties.put("org.eclipse.persistence.jaxb.IDRESOLVER", new IDResolver() {
    @Override
    public Object resolve(Object id, XMLNode node, Unmarshaller unmarshaller) throws SAXException {
        // 直接返回原始ID字符串,不进行实体解析
        return id;
    }

    @Override
    public void bind(Object id, Object obj, XMLNode node, Unmarshaller unmarshaller) throws SAXException {
        // 绑定操作无需处理
    }
});

DynamicJAXBContext dynamicContext = DynamicJAXBContextFactory.createContextFromXSD(xmlSchema, entityResolver, classLoader, properties);

方式2:通过jaxb.properties全局配置

在类路径下创建jaxb.properties文件,指定自定义的IDResolver实现类:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
org.eclipse.persistence.jaxb.IDRESOLVER=com.yourpackage.NoOpIDResolver

然后实现NoOpIDResolver类:

public class NoOpIDResolver extends IDResolver {
    @Override
    public Object resolve(Object id, XMLNode node, Unmarshaller unmarshaller) throws SAXException {
        return id;
    }

    @Override
    public void bind(Object id, Object obj, XMLNode node, Unmarshaller unmarshaller) throws SAXException {
        // 空实现
    }
}

这样配置后,MOXy遇到IDREF类型的属性时,会直接保留原始的ID字符串,不会自动解析为实体对象,彻底替代手动替换的临时方案,也避免了对属性名的硬编码依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:52:41