使用Jackson XmlMapper解析XML时将field属性映射为Map键值对失败求助
问题原因
你当前的配置下,Jackson无法识别需要将field标签的name属性作为Map键、标签文本作为Map值,只会将每个field节点整体作为值存入Map,且统一使用field作为键,因此最终只会保留最后一个field节点的内容,也就是你看到的META_4的结果。
解决方案
推荐使用兼容性更强的「先映射为List再转Map」方案,无需依赖高版本Jackson特性,稳定性更高:
步骤1:新增Field映射类
新增一个临时映射类接收每个field节点的内容:
@Data public static class Field { // 指定映射name属性 @JacksonXmlProperty(isAttribute = true) private String name; // 指定映射标签内的文本内容 @JacksonXmlText private String value; }
步骤2:修改POJO的fields配置
将原Map类型的fields改为List接收所有field节点,额外新增getFields方法转换为你需要的Map结构:
@Data @XmlRootElement(name = "data") public class MetaDataSharePoint { @JacksonXmlProperty(localName = "contentType") private String contentType; @JacksonXmlProperty private String siteName; @JacksonXmlProperty private String listName; @JacksonXmlProperty private String folderName; @JacksonXmlProperty private String documentSetName; // 改为List接收所有field节点 @JacksonXmlElementWrapper(localName = "fields") @JacksonXmlProperty(localName = "field") private List<Field> fieldList; // 新增方法转换为目标Map结构 public Map<String, String> getFields() { if (fieldList == null) { return Collections.emptyMap(); } return fieldList.stream() .collect(Collectors.toMap(Field::getName, Field::getValue)); } }
步骤3:简化解析代码
不需要手动操作XMLStreamReader,直接传入File对象读取即可,避免节点定位错误:
public static void main(String[] args) throws IOException { String path = "src/test/resources/bill.xml"; XmlMapper mapper = XmlMapper.builder() .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); MetaDataSharePoint metaDataSharePoint = mapper.readValue(new File(path), MetaDataSharePoint.class); // 测试输出和原来完全一致 System.out.println(metaDataSharePoint); System.out.println("contentType : " + metaDataSharePoint.getContentType()); System.out.println("DocumentSetName : " + metaDataSharePoint.getDocumentSetName()); System.out.println("ListName : " + metaDataSharePoint.getListName()); System.out.println("SiteName : " + metaDataSharePoint.getSiteName()); System.out.println("FolderName : " + metaDataSharePoint.getFolderName()); metaDataSharePoint.getFields().forEach((key, value) -> { System.out.println("key: " + key); System.out.println("value: " + value); }); }
运行后就能得到你期望的输出结果。
内容的提问来源于stack exchange,提问作者davidvera
相关产品推荐
相关产品推荐

