0

0

使用Jackson在Spring Boot中解析XML列表的正确姿势

霞舞

霞舞

发布时间:2025-10-01 14:19:34

|

319人浏览过

|

来源于php中文网

原创

使用Jackson在Spring Boot中解析XML列表的正确姿势

本文旨在解决在Spring Boot应用中使用Jackson解析包含重复子元素的XML文件时,仅解析到最后一个元素的问题。通过详细分析@JacksonXmlElementWrapper和@JacksonXmlProperty注解的正确用法,特别是useWrapping = false属性,指导读者构建与XML结构精确匹配的Java模型,确保所有列表元素都能被成功解析,并提供完整的代码示例。

引言

java spring boot项目中处理xml数据是常见的任务,jackson库凭借其强大的功能和灵活的注解,成为解析xml的首选工具之一。然而,对于初学者来说,当xml中包含重复的同名子元素(如列表)时,可能会遇到解析不完整,只获取到最后一个元素的情况。本文将深入探讨这一问题,并提供一个清晰、专业的解决方案。

问题描述

假设我们有一个XML文件,其中包含一个cpe-list根元素,内部有多个cpe-item子元素,每个cpe-item又包含name属性和title子元素,结构如下:



    
        xmlread
    
    
        testtitle
    

我们希望将这个XML解析成Java对象,其中cpe-list对应一个包含CpeItem对象列表的Java类。然而,在初步尝试中,我们可能会发现Jackson只解析了name="Jack"的cpe-item,而name="John"的cpe-item则被遗漏了。这通常是由于Java模型中的Jackson注解使用不当导致的。

Jackson XML解析核心注解

要正确解析XML,理解Jackson提供的几个关键注解至关重要:

  • @JacksonXmlRootElement(localName = "..."): 用于指定Java类对应的XML根元素名称。
  • @JacksonXmlProperty(localName = "...", isAttribute = true/false): 用于将Java字段映射到XML元素或属性。isAttribute = true表示映射到属性,否则映射到子元素。
  • @JacksonXmlElementWrapper(localName = "...", useWrapping = true/false): 专门用于处理集合(List, Set等)类型字段。
    • localName: 如果useWrapping = true,则指定包裹集合的XML元素名称。
    • useWrapping = true(默认值):表示集合元素被一个额外的XML元素包裹。例如,12
    • useWrapping = false: 表示集合元素直接作为父元素的子元素出现,没有额外的包裹层。例如,12

解决方案:正确构建Java模型

问题的核心在于CpeList类中对cpe-item列表的映射。原始尝试中,可能将cpeItems字段定义为单个CpeItem对象,或者使用了不当的@JacksonXmlElementWrapper配置。

根据上述XML结构,cpe-list直接包含多个cpe-item子元素,这些cpe-item没有被额外的父元素包裹。因此,我们需要在CpeList类中将cpe-item映射为一个CpeItem对象的列表,并且关键在于使用@JacksonXmlElementWrapper(useWrapping = false)来指示Jackson这些列表元素没有额外的包裹层。

1. CpeItem 类

CpeItem类用于表示单个元素。它的结构相对简单,直接映射name属性和title子元素。

package com.dependency.demo;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;

@Data
@JacksonXmlRootElement(localName = "cpe-item") // 指明此Java类对应XML中的cpe-item元素
public class CpeItem {
    @JacksonXmlProperty(localName = "name", isAttribute = true) // name是cpe-item的属性
    private String name;

    // title是cpe-item的子元素,Jackson默认会根据字段名匹配
    private String title;
}

2. CpeList 类

CpeList类是解决问题的关键。它需要包含一个CpeItem对象的列表。

PNG Maker
PNG Maker

利用 PNG Maker AI 将文本转换为 PNG 图像。

下载
package com.dependency.demo;

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 lombok.Data;

import java.util.List;

@Data
@JacksonXmlRootElement(localName = "cpe-list") // 指明此Java类对应XML中的cpe-list根元素
public class CpeList {

    // 关键在于这里:
    // @JacksonXmlElementWrapper(useWrapping = false) 表示cpe-item元素没有额外的包裹层
    // @JacksonXmlProperty(localName = "cpe-item") 表示集合中的每个元素都对应一个名为cpe-item的XML子元素
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "cpe-item")
    private List cpeItems; // 使用List来存储多个CpeItem对象
}

3. XmlController 类

控制器负责读取XML文件并使用XmlMapper进行解析。

package com.dependency.demo;

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@RestController
public class XmlController {

    @GetMapping("/parse-xml") // 明确指定一个端点路径
    public CpeList parseCpeListXml() throws XMLStreamException, IOException {
        // 从类路径加载XML文件
        InputStream xmlResource = XmlController.class.getClassLoader().getResourceAsStream("test.xml");
        if (xmlResource == null) {
            throw new IOException("XML file 'test.xml' not found in classpath.");
        }

        // 使用XMLInputFactory创建XMLStreamReader,Jackson内部会使用它
        XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlResource);

        // 创建XmlMapper实例
        XmlMapper mapper = new XmlMapper();
        // 如果XML中存在Java模型中没有的字段,可以配置忽略,避免解析失败
        // mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 执行XML到Java对象的反序列化
        CpeList cpeList = mapper.readValue(xmlStreamReader, CpeList.class);

        // 打印解析结果以验证
        if (cpeList != null && cpeList.getCpeItems() != null) {
            System.out.println("Parsed CpeList with " + cpeList.getCpeItems().size() + " items.");
            for (CpeItem item : cpeList.getCpeItems()) {
                System.out.println("  CPE Item - Name: " + item.getName() + ", Title: " + item.getTitle());
            }
        }

        return cpeList;
    }
}

test.xml 文件内容 (放置在 src/main/resources 目录下):



    
        xmlread
    
    
        testtitle
    
    
        another_title
    

运行与验证

启动Spring Boot应用后,访问 /parse-xml 端点(例如 http://localhost:8080/parse-xml),你将看到如下输出:


    
        xmlread
    
    
        testtitle
    
    
        another_title
    

以及控制台输出:

Parsed CpeList with 3 items.
  CPE Item - Name: John, Title: xmlread
  CPE Item - Name: Jack, Title: testtitle
  CPE Item - Name: Jane, Title: another_title

这表明所有cpe-item元素都被成功解析并映射到了CpeList中的cpeItems列表。

注意事项与最佳实践

  1. XML与Java模型结构匹配: 确保Java类的结构(包括根元素、子元素、属性以及列表的包裹方式)与实际XML文件的结构完全匹配。这是成功解析XML的基础。
  2. @JacksonXmlElementWrapper 的 useWrapping 属性: 这是处理列表的关键。当XML中列表元素没有额外的父元素包裹时,务必设置useWrapping = false。
  3. 错误处理: 在实际应用中,应添加更健壮的错误处理机制,例如捕获IOException和XMLStreamException,并提供有意义的错误信息。
  4. DeserializationFeature: XmlMapper提供了许多配置选项,例如mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);可以忽略XML中存在但Java模型中没有的字段,提高解析的容错性。
  5. 资源管理: 确保InputStream等资源在使用完毕后被正确关闭,避免资源泄露。在Spring Boot中,如果使用@RequestBody直接接收XML,Spring会自动处理这些。
  6. Lombok: 示例中使用了Lombok的@Data注解,它会自动生成Getter、Setter、equals()、hashCode()和toString()方法,简化了POJO的编写。

总结

通过本文的讲解,我们深入理解了在Spring Boot中使用Jackson解析XML列表时,@JacksonXmlElementWrapper和@JacksonXmlProperty注解的关键作用。特别是在处理没有额外包裹层的列表元素时,正确配置@JacksonXmlElementWrapper(useWrapping = false)是确保所有列表项都被成功解析的关键。遵循这些原则,可以有效避免常见的XML解析陷阱,构建出健壮且准确的XML数据处理逻辑。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

114

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

29

2026.01.26

spring boot框架优点
spring boot框架优点

spring boot框架的优点有简化配置、快速开发、内嵌服务器、微服务支持、自动化测试和生态系统支持。本专题为大家提供spring boot相关的文章、下载、课程内容,供大家免费下载体验。

135

2023.09.05

spring框架有哪些
spring框架有哪些

spring框架有Spring Core、Spring MVC、Spring Data、Spring Security、Spring AOP和Spring Boot。详细介绍:1、Spring Core,通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度;2、Spring MVC,提供基于模型-视图-控制器的架构,用于开发灵活和可扩展的Web应用程序等。

390

2023.10.12

Java Spring Boot开发
Java Spring Boot开发

本专题围绕 Java 主流开发框架 Spring Boot 展开,系统讲解依赖注入、配置管理、数据访问、RESTful API、微服务架构与安全认证等核心知识,并通过电商平台、博客系统与企业管理系统等项目实战,帮助学员掌握使用 Spring Boot 快速开发高效、稳定的企业级应用。

70

2025.08.19

Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性
Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性

Spring Boot 是一个基于 Spring 框架的 Java 开发框架,它通过 约定优于配置的原则,大幅简化了 Spring 应用的初始搭建、配置和开发过程,让开发者可以快速构建独立的、生产级别的 Spring 应用,无需繁琐的样板配置,通常集成嵌入式服务器(如 Tomcat),提供“开箱即用”的体验,是构建微服务和 Web 应用的流行工具。

34

2025.12.22

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

135

2025.12.24

pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1900

2024.04.01

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

142

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

C# 教程
C# 教程

共94课时 | 7.8万人学习

Java 教程
Java 教程

共578课时 | 52.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号