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

无法将XML转换为POJO,解析时引用链出现异常

XML转POJO解析失败的解决方案(Jackson XmlMapper)

问题背景

从Web服务获取的XML响应无法通过Jackson XmlMapper转换为POJO,报错信息如下:

test failed Unrecognized field "Step" (class com.adapters.ccr.ApaData), not marked as ignorable (3 known properties: "processCode", "processLabel", "steps"]) at [Source: (StringReader); line: 6, column: 18] (through reference chain: com.adapters.ccr.ApaData["Step"])

核心矛盾:预期XML包含<Steps>父标签,但实际响应中直接是多个<Step>元素,同时存在字段名大小写不匹配、XML命名空间未处理的问题。

原POJO类

public class ApaData {
    private String processCode;
    private String processLabel;
    private List<Step> steps;
}

public class Step {
    private Integer StepNum;
    private String StepStatus;
    private String StepLabel;
}

实际XML响应

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<APA_Data xmlns="http://www.test.com/atlas/apa/v1">
    <ProcessCode>4</ProcessCode>
    <ProcessLabel>information is invalid.</ProcessLabel>
    <Step>
        <StepNum>1</StepNum>
        <StepStatus>9</StepStatus>
        <StepLabel>Decryption not attempted.</StepLabel>
    </Step>
    <Step>
        <StepNum>2</StepNum>
        <StepStatus>9</StepStatus>
        <StepLabel>Digital signature verification not attempted.</StepLabel>
    </Step>
</APA_Data>

解决方案

通过Jackson的XML注解调整POJO映射规则,同时处理命名空间和列表包装问题:

修改后的POJO类

ApaData类

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.List;

@JacksonXmlRootElement(localName = "APA_Data", namespace = "http://www.test.com/atlas/apa/v1")
public class ApaData {
    @JacksonXmlProperty(localName = "ProcessCode", namespace = "http://www.test.com/atlas/apa/v1")
    private String processCode;

    @JacksonXmlProperty(localName = "ProcessLabel", namespace = "http://www.test.com/atlas/apa/v1")
    private String processLabel;

    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "Step", namespace = "http://www.test.com/atlas/apa/v1")
    private List<Step> steps;

    // 必须添加Getter/Setter方法,Jackson依赖反射访问字段
    public String getProcessCode() { return processCode; }
    public void setProcessCode(String processCode) { this.processCode = processCode; }
    public String getProcessLabel() { return processLabel; }
    public void setProcessLabel(String processLabel) { this.processLabel = processLabel; }
    public List<Step> getSteps() { return steps; }
    public void setSteps(List<Step> steps) { this.steps = steps; }
}

Step类

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

public class Step {
    @JacksonXmlProperty(localName = "StepNum", namespace = "http://www.test.com/atlas/apa/v1")
    private Integer stepNum;

    @JacksonXmlProperty(localName = "StepStatus", namespace = "http://www.test.com/atlas/apa/v1")
    private String stepStatus;

    @JacksonXmlProperty(localName = "StepLabel", namespace = "http://www.test.com/atlas/apa/v1")
    private String stepLabel;

    // Getter/Setter方法
    public Integer getStepNum() { return stepNum; }
    public void setStepNum(Integer stepNum) { this.stepNum = stepNum; }
    public String getStepStatus() { return stepStatus; }
    public void setStepStatus(String stepStatus) { this.stepStatus = stepStatus; }
    public String getStepLabel() { return stepLabel; }
    public void setStepLabel(String stepLabel) { this.stepLabel = stepLabel; }
}

关键注解说明

  • @JacksonXmlRootElement:绑定XML根节点名称和命名空间,与响应中的<APA_Data>完全匹配。
  • @JacksonXmlProperty:解决POJO驼峰字段与XML大写字段的映射问题,同时指定命名空间避免解析失败。
  • @JacksonXmlElementWrapper(useWrapping = false):核心配置,告诉Jackson不需要为列表寻找父标签(如<Steps>),直接将所有<Step>元素收集到steps列表中。

简化配置(忽略命名空间)

如果不想每个字段都指定命名空间,可以通过XmlMapper配置全局忽略命名空间:

import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class XmlParser {
    public static void main(String[] args) throws Exception {
        XmlMapper xmlMapper = XmlMapper.builder()
                .configure(com.fasterxml.jackson.dataformat.xml.XmlParser.Feature.IGNORE_NAMESPACE, true)
                .build();
        
        // 后续解析代码不变
        ApaData data = xmlMapper.readValue(xmlString, ApaData.class);
    }
}

此时POJO注解中的namespace参数可以省略,进一步简化代码。

测试验证

运行修改后的解析代码,即可成功将XML转换为ApaData对象,获取所有字段和步骤数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 06:27:11