使用jackson-dataformat-xml反序列化带外层包装的XML如何避免创建包装类
方案1:直接解析XML树后提取内层节点(推荐,单次场景最简便)
直接用XmlMapper先将XML解析为树节点,再提取内层的person节点完成反序列化,无需自定义流操作,也不需要额外创建包装类,代码如下:
XmlMapper xmlMapper = new XmlMapper(); // 第一步:先把整个XML解析为树节点 JsonNode rootNode = xmlMapper.readTree(inputXml); // 第二步:提取内层person节点,转为Person对象 Person person = xmlMapper.treeToValue(rootNode.get("person"), Person.class);
这种方案也规避了你手动移动XMLStreamReader指针可能遇到的空白节点、注释节点等异常情况,稳定性更高。
如果你的项目还未引入Jackson XML依赖,需要在pom.xml中添加,Spring Boot 2.5.4会自动管理版本无需手动指定:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
方案2:封装通用工具方法适配多场景
如果有大量类似的外层包装标签的反序列化需求,可以把逻辑封装为通用工具方法:
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.dataformat.xml.XmlMapper; public class XmlUtils { private static final XmlMapper XML_MAPPER = new XmlMapper(); /** * 反序列化带外层包装标签的XML * @param xml 输入XML字符串 * @param innerNodeName 内层实际对象对应的节点名 * @param clazz 目标反序列化类 * @return 反序列化后的对象 */ public static <T> T readXmlWithWrapper(String xml, String innerNodeName, Class<T> clazz) throws JsonProcessingException { JsonNode rootNode = XML_MAPPER.readTree(xml); return XML_MAPPER.treeToValue(rootNode.get(innerNodeName), clazz); } }
调用方式:
Person person = XmlUtils.readXmlWithWrapper(inputXml, "person", Person.class);
之前方案报错的原因
你使用withRootName("person")时,Jackson仅会校验根节点的名称是否匹配,不会自动跳过外层包装节点,此时<person_wrapper>根节点下的<person>标签会被识别为Person类的未知属性,因此抛出UnrecognizedPropertyException异常。
内容的提问来源于stack exchange,提问作者George Lvov
相关产品推荐
相关产品推荐

