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

Jackson XML无法正确解析嵌套对象,返回空对象问题求助

Hey, let's dig into this Jackson XML parsing issue you're facing. It's tricky when parts work in isolation but break in the full context—here's what I think is going on and how to fix it:

Problem Analysis & Fixes

From your description, the core issue is that Group's array/struct collections come back null when parsing the full XML, but work fine when testing individual fragments. This almost always boils down to subtle mismatches between XML structure and Jackson annotations, plus potential XML validity issues that only surface in full-document parsing.

Let's break down the root causes and fixes step by step:

1. First: Fix the Invalid XML

Looking at your sample XML, there's an unclosed <define> node inside the <struct name="compatibility_"> block. When parsing the full document, this invalid structure can throw off Jackson's parser, causing it to skip or misinterpret subsequent nodes (like your <array>). When testing fragments, you probably fixed this accidentally, hence why it worked there.

Here's the corrected XML snippet:

<config>
  <group name="sys">
    <desc>sss</desc>
    <define name="DYN">
      <const>1</const>
      <desc> </desc>
    </define>
    <par name="show_time" type="ACT" len="1">
      <snmp oid="1">ssss</snmp>
      <val>0</val>
      <desc>Show system</desc>
    </par>
    <struct name="compatibility_">
      <desc> </desc>
      <par name="link" type="PAR" len="1" range="0,1">
        <snmp oid="232">ssss</snmp>
        <val>0</val>
        <desc> </desc>
      </par>
      <define name="POLL_AND_INTERRUPT">
        <mask>0</mask>
        <desc> </desc>
      </define> <!-- Fixed: closed this node -->
    </struct>
    <array name="DYN_STRUCT" len="1" max="32">
      <struct name="script_" key="name">
        <desc> </desc>
        <par name="name" type="STRING" len="32"> </par>
      </struct>
    </array>
  </group>
</config>

2. Align Jackson Annotations with XML Structure

Your existing annotations are close, but missing some key details that help Jackson map nested nodes and attributes correctly.

Updated Group Class

We need to explicitly link the list fields to their XML node names, and add mappings for attributes like name that exist on the <group> node:

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class Group {
    // Combine wrapper and property annotations to explicitly map <array> nodes
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "array")
    private List<Array> array = new ArrayList<>();

    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "struct")
    private List<Struct> struct = new ArrayList<>();

    // Map the "name" attribute on <group>
    @JacksonXmlProperty(isAttribute = true)
    private String name;

    // Map the <desc> child node
    @JacksonXmlProperty(localName = "desc")
    private String desc;
}

Updated Array Class

The struct field needs an explicit node name mapping, and we should add mappings for the attributes on the <array> node (like name, len) to avoid parsing conflicts:

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class Array {
    @JacksonXmlProperty(localName = "struct")
    private Struct struct;

    @JacksonXmlProperty(isAttribute = true)
    private String name;

    @JacksonXmlProperty(isAttribute = true)
    private Integer len;

    @JacksonXmlProperty(isAttribute = true)
    private Integer max;
}

Updated Struct Class

Keep your existing setup, but add mappings for the <struct> node's attributes and child nodes to ensure consistency:

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class Struct {
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "par")
    private List<Par> par = new ArrayList<>();

    @JacksonXmlProperty(isAttribute = true)
    private String name;

    @JacksonXmlProperty(localName = "desc")
    private String desc;
}

3. Parsing Code Example

Make sure you're using the XmlMapper correctly, and wrap the root <config> node in a matching class (since your XML starts with <config>):

// Define a wrapper class for the root <config> node
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class Config {
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "group")
    private List<Group> group;
}

// Parse the XML
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Config config = xmlMapper.readValue(yourXmlString, Config.class);
Group sysGroup = config.getGroup().stream()
    .filter(g -> "sys".equals(g.getName()))
    .findFirst()
    .orElse(null);

// Now sysGroup's array and struct lists should populate correctly

Key Verification Checks

  • The invalid XML was likely the biggest culprit—full-document parsers are strict about well-formedness, while fragment testing may have overlooked the unclosed node.
  • Explicitly annotating attributes and node names removes ambiguity for Jackson, which is critical when dealing with nested collections.
  • Using @JsonIgnoreProperties(ignoreUnknown = true) prevents unexpected nodes (like <define> or <par> in <group>) from breaking the parsing flow.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:28:57