Jackson XML反序列化为Java LinkedTreeMap结果不符问题咨询
解决Jackson XML转Map时结构不符合预期的问题
我明白你遇到的困扰——用Jackson的XmlMapper把这段XML转成LinkedTreeMap时,实际得到的结构和你预想的不一样。先帮你拆解下问题原因,再给你几个可行的解决方案:
问题根源
默认情况下Jackson XML反序列化有两个核心行为会导致结构不符:
- 标签大小写保留:XML里的
<Properties>标签会被直接映射成Map的键"Properties"(而不是你预期的小写"properties"); - 重复子节点的默认处理:
<runList>下的多个<runID>会被包裹在一个以"runID"为键的List里,默认得到的结构大概是:
这和你想要的索引式Map或扁平化结构有明显差异。{ "Properties": { "runList": { "runID": [6656, 6657] } } }
解决方案1:直接配置XmlMapper并调整结构
如果你不想定义POJO,只想直接转成Map并调整为预期结构,可以这么操作:
步骤1:配置XmlMapper忽略键的大小写
先让Mapper支持大小写不敏感的键映射,把"Properties"自动转为"properties":
XmlMapper xmlMapper = XmlMapper.builder() .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) .build();
步骤2:转换并手动调整结构
把默认得到的Map里的runID列表转成索引式Map:
String xmlContent = "<Properties> <runList> <runID>6656</runID> <runID>6657</runID> </runList> </Properties>"; Map<String, Object> originalMap = xmlMapper.readValue(xmlContent, Map.class); // 调整为你预期的结构 Map<String, Object> properties = (Map<String, Object>) originalMap.get("properties"); Map<String, Object> runList = (Map<String, Object>) properties.get("runList"); List<Integer> runIDs = (List<Integer>) runList.get("runID"); Map<String, Object> targetRunList = new LinkedHashMap<>(); for (int i = 0; i < runIDs.size(); i++) { targetRunList.put(String.valueOf(i), runIDs.get(i)); } properties.put("runList", targetRunList); // 最终结构:{ properties => { runList => { 0=> 6656, 1=> 6657 } } } System.out.println(originalMap);
解决方案2:用POJO精准控制结构(更推荐)
如果希望序列化逻辑更可控,先定义匹配XML的POJO,再转成目标Map结构:
定义匹配XML的POJO
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import java.util.List; public class Properties { // 禁用runList的包装,直接把runID作为列表元素 @JacksonXmlElementWrapper(useWrapping = false) private List<Integer> runID; // Getter和Setter public List<Integer> getRunID() { return runID; } public void setRunID(List<Integer> runID) { this.runID = runID; } }
反序列化并转换为目标Map
XmlMapper xmlMapper = new XmlMapper(); Properties props = xmlMapper.readValue(xmlContent, Properties.class); // 构建你想要的Map结构 Map<String, Object> resultMap = new LinkedHashMap<>(); Map<String, Object> runListMap = new LinkedHashMap<>(); for (int i = 0; i < props.getRunID().size(); i++) { runListMap.put(String.valueOf(i), props.getRunID().get(i)); } resultMap.put("properties", Map.of("runList", runListMap)); // 输出结果即为你预期的结构 System.out.println(resultMap);
内容的提问来源于stack exchange,提问作者SparkNee
相关产品推荐
相关产品推荐

