使用XmlMapper读取XML返回root=null,Java模型类是否有误?
问题原因及修复方案
1. XML文件存在语法错误
你的XML有两处语法问题,会直接导致解析逻辑混乱:
<Header>只有闭合标签</Header>,缺少开始标签<Header><Value>的闭合标签错误写成</Item>,应改为</Value>
修正后的XML:
<?xml version="1.0" encoding="ISO-8859-1"?> <Root version="1.0"> <Header/> <Value line="1"> <Id> 20868PW </Id> <Price> 7 </Price> </Value> </Root>
2. 注解不匹配:XmlMapper默认不识别JAXB注解
你用的是Jackson的XmlMapper,但模型类用的是JAXB的@XmlElement、@XmlRootElement注解,Jackson默认不会处理这些注解,有两种修复方式:
方案一:改用Jackson XML专属注解
直接调整模型类使用Jackson XML模块的注解,同时修正结构匹配XML根节点:
// RootResponse.java import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; @JacksonXmlRootElement(localName = "Root") public class RootResponse { @JacksonXmlProperty(localName = "Value") private List<Value> value; @JacksonXmlProperty(localName = "Header") private List<Header> header; @JacksonXmlProperty(isAttribute = true) private String version; // 必须添加所有字段的getter/setter方法 }
同时修改读取代码,直接解析RootResponse:
private RootResponse getMockResponse() throws IOException { XmlMapper xmlMapper = new XmlMapper(); File file = new File("src/test/MockedFile.xml"); return xmlMapper.readValue(file, RootResponse.class); }
方案二:开启Jackson对JAXB注解的支持
如果坚持用JAXB注解,需先添加jackson-module-jaxb-annotations依赖,再配置XmlMapper:
private MyResponse getMockResponse() throws IOException { XmlMapper xmlMapper = new XmlMapper(); xmlMapper.registerModule(new JaxbAnnotationModule()); File file = new File("src/test/MockedFile.xml"); return xmlMapper.readValue(file, MyResponse.class); }
注意:此时需修正MyResponse的结构——你的XML根节点是<Root>,但MyResponse里的root字段用@XmlElement(name="Root"),意味着MyResponse对应一个包含<Root>子节点的父节点,和现有XML结构不匹配,建议直接让RootResponse作为解析目标。
3. 模型类缺少getter/setter方法
Jackson必须通过getter/setter访问私有字段,你的模型类只定义了字段,没有提供访问方法,会导致无法赋值,最终返回null,必须为所有需要映射的字段添加getter和setter。
4. 文件路径验证
确认src/test/MockedFile.xml路径正确,JUnit测试默认资源路径是src/test/resources,如果文件放在这里,建议用流读取更可靠:
private RootResponse getMockResponse() throws IOException { XmlMapper xmlMapper = new XmlMapper(); try (InputStream is = getClass().getResourceAsStream("/MockedFile.xml")) { return xmlMapper.readValue(is, RootResponse.class); } }
内容的提问来源于stack exchange,提问作者Karin
相关产品推荐
相关产品推荐

