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

Jackson XML反序列化报错:无法从字符串值构造实例

Jackson XML反序列化报错解决方案

问题背景

尝试用POJO反序列化XML时触发如下错误,无法正确解析列表类型字段:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of TestData (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('checka')
at [Source: (com.ctc.wstx.sr.ValidatingStreamReader); line: 3, column: 15] (through reference chain: TC["testData"]->java.util.ArrayList[0])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)

待解析的XML内容:

<tc>
<testData>
    <post>checka</post>
    <xtenantid>netwebshopa</xtenantid>
    <jsonbody>Testa</jsonbody>
</testData>
<testData>
    <post>check</post>
    <xtenantid>netwebshop</xtenantid>
    <jsonbody>Test</jsonbody>
</testData>
</tc>

对应的POJO代码:

TC类

@JacksonXmlRootElement(localName = "tc")
public class TC {

private List<TestData> testData;

public List<TestData> getTestData() {
    return testData;
}

public void setTestData(List<TestData> testData) {
    this.testData = testData;
}

}

TestData类

public class TestData {
    
private String post;
private String xtenantid;
private String jsonbody;

public String getPost() {
    return post;
}
public void setPost(String post) {
    this.post = post;
}
public String getXtenantid() {
    return xtenantid;
}
public void setXtenantid(String xtenantid) {
    this.xtenantid = xtenantid;
}
public String getJsonbody() {
    return jsonbody;
}
public void setJsonbody(String jsonbody) {
    this.jsonbody = jsonbody;
}

}

问题原因

Jackson XML默认会为列表类型字段寻找外层包裹节点(比如期望用<testDatas>包裹所有<testData>节点),但当前XML结构中直接是多个<testData>作为<tc>的子节点,没有外层包裹。这导致Jackson误将<testData>下的第一个子节点<post>的内容当成了列表项的字符串值,进而尝试用字符串构造TestData对象,触发报错。

解决步骤

修改TC类的testData字段,添加两个注解明确解析规则:

  1. @JacksonXmlElementWrapper(useWrapping = false):禁用列表的外层包裹节点解析,直接将所有同名的<testData>节点作为列表元素。
  2. @JacksonXmlProperty(localName = "testData"):显式绑定XML节点名称与Java字段,避免命名规则差异导致的映射错误。

修改后的TC类代码:

@JacksonXmlRootElement(localName = "tc")
public class TC {

    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "testData")
    private List<TestData> testData;

    public List<TestData> getTestData() {
        return testData;
    }

    public void setTestData(List<TestData> testData) {
        this.testData = testData;
    }
}

额外注意:确保项目中jackson-dataformat-xml依赖版本与jackson-databind保持一致,避免版本冲突引发其他异常。

内容的提问来源于stack exchange,提问作者Madhav Gutte

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:54:40