Jackson XmlMapper反序列化时XML属性处理异常求助
解决Jackson XML转JsonNode后属性变子标签的问题
核心原因
Jackson XML模块默认会把XML属性转为带@前缀的JsonNode节点,但如果配置不当,反序列化时属性会丢失前缀,导致序列化回XML时被识别为子标签而非属性。
解决方案
通过配置XmlMapper,明确标记XML属性的前缀,并确保序列化时识别该前缀为属性:
- 初始化配置正确的XmlMapper
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature; // 创建XML模块并配置 JacksonXmlModule xmlModule = new JacksonXmlModule(); // 禁用根节点包装,避免额外嵌套 xmlModule.setDefaultUseWrapper(false); XmlMapper xmlMapper = XmlMapper.builder(xmlModule) // 明确设置XML属性在JsonNode中的前缀为@ .configure(FromXmlParser.Feature.ATTR_PREFIX, "@") // 禁用根节点序列化包装 .configure(SerializationFeature.WRAP_ROOT_VALUE, false) // 禁用根节点反序列化解包 .configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false) .build();
- 处理Xml转JsonNode及修改
原XML示例:
<root> <innerField1 innerField1Attribute="originalValue">some content</innerField1> </root>
转成JsonNode后,属性会被标记为@innerField1Attribute:
{ "innerField1": { "@innerField1Attribute": "originalValue", "#text": "some content" } }
修改时直接操作带@前缀的节点:
JsonNode rootNode = xmlMapper.readTree(xmlString); ObjectNode innerFieldNode = (ObjectNode) rootNode.get("innerField1"); // 修改属性值 innerFieldNode.put("@innerField1Attribute", "newValue");
- 转回XML
String modifiedXml = xmlMapper.writeValueAsString(rootNode);
输出的XML会保留属性:
<root> <innerField1 innerField1Attribute="newValue">some content</innerField1> </root>
注意事项
- 必须确保JsonNode中属性节点以
@开头,否则序列化时会被当作子标签 - 2.11.1版本的Jackson中
FromXmlParser.Feature.ATTR_PREFIX默认值为@,但显式配置可避免环境差异导致的问题 - 不要随意修改属性前缀规则,否则会破坏Jackson对XML属性的识别逻辑
内容的提问来源于stack exchange,提问作者Ant
相关产品推荐
相关产品推荐

