如何禁用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
相关产品推荐
相关产品推荐

