0

0

使用Jackson在Spring Boot中解析XML列表的教程

DDD

DDD

发布时间:2025-10-01 12:59:17

|

586人浏览过

|

来源于php中文网

原创

使用Jackson在Spring Boot中解析XML列表的教程

本文详细介绍了在Java Spring Boot应用中,如何使用Jackson库解析包含重复元素的XML文件。重点讲解了如何正确配置@JacksonXmlElementWrapper和@JacksonXmlProperty注解,以将XML中的多个同名子元素映射到Java对象中的List集合,并提供了完整的代码示例和解析原理,帮助开发者避免仅解析到最后一个元素的常见问题

1. 引言:使用Jackson解析XML的挑战

在spring boot应用中处理xml数据是常见的任务,jackson库通过其jackson-dataformat-xml模块提供了强大的xml解析能力。然而,对于初学者来说,当xml中包含多个同名且需要被解析为java list集合的元素时,可能会遇到只解析到最后一个元素的问题。本教程将通过一个具体的示例,详细阐述如何正确配置jackson注解来解决这一问题。

考虑以下XML结构:



    
        xmlread
    
    
        testtitle
    

我们的目标是将下的所有元素解析到一个Java对象的List中。

2. 定义数据模型(POJO)

首先,我们需要定义与XML结构相对应的Java POJO(Plain Old Java Object)。

2.1 CpeItem 类

CpeItem代表XML中的元素。它有一个属性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")
public class CpeItem {
    @JacksonXmlProperty(localName = "name", isAttribute = true)
    private String name;

    private String title; // Jackson默认会将其映射到同名子元素

}
  • @Data: Lombok注解,自动生成getter、setter、equals、hashCode和toString方法。
  • @JacksonXmlRootElement(localName = "cpe-item"): 指定该POJO对应XML中的根元素名为cpe-item。
  • @JacksonXmlProperty(localName = "name", isAttribute = true): 将XML元素cpe-item的name属性映射到Java对象的name字段。isAttribute = true表明它是一个属性而非子元素。
  • private String title;: 对于非属性的子元素,Jackson默认会根据字段名匹配XML子元素名。

2.2 CpeList 类:关键的列表解析

CpeList类代表XML的根元素,它需要包含一个CpeItem的列表。这是解析多个同名元素的关键。

错误的尝试(仅解析最后一个元素):

最初的尝试可能像这样:

// 错误示例:仅解析最后一个cpe-item
package com.dependency.demo;

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

import java.util.List; // 即使这里是List,但注解配置不当也会出错

@Data
@JacksonXmlRootElement(localName = "cpe-list")
public class CpeList {
    // 假设这样可以,但实际上会失败或只解析最后一个
    @JacksonXmlElementWrapper(localName = "cpe-item") // 这里是问题所在
    private CpeItem cpeItems; // 或者 List cpeItems; 但JacksonXmlElementWrapper的配置错误
}

上述代码中,如果cpeItems是CpeItem类型,Jackson会尝试将所有元素映射到这一个字段,结果就是只有最后一个元素被保留。即使将cpeItems改为List,@JacksonXmlElementWrapper(localName = "cpe-item")的配置也可能导致问题,因为它期望cpe-item是一个包装器元素,而不是列表中的实际元素。

正确的 CpeList 类配置:

为了正确解析XML中的多个元素到一个List中,我们需要使用@JacksonXmlElementWrapper和@JacksonXmlProperty的组合。

微信 WeLM
微信 WeLM

WeLM不是一个直接的对话机器人,而是一个补全用户输入信息的生成模型。

下载
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")
public class CpeList {
    @JacksonXmlElementWrapper(useWrapping = false) // 关键:不使用额外的包装元素
    @JacksonXmlProperty(localName = "cpe-item") // 关键:指定列表元素的名称
    private List cpeItems; // 将多个cpe-item映射到此列表
}
  • @JacksonXmlRootElement(localName = "cpe-list"): 指定该POJO对应XML中的根元素名为cpe-list。
  • @JacksonXmlElementWrapper(useWrapping = false): 这是解决问题的关键。它告诉Jackson,XML中没有一个额外的“包装器”元素来包含cpe-item列表。在我们的XML中,元素直接是的子元素,没有像这样的结构,所以useWrapping必须设置为false。
  • @JacksonXmlProperty(localName = "cpe-item"): 指定列表中每个元素的XML名称为cpe-item。Jackson会找到所有名为cpe-item的子元素,并将它们反序列化为CpeItem对象,然后添加到cpeItems列表中。

3. 实现XML解析控制器

在Spring Boot中,我们通常会创建一个REST控制器来处理HTTP请求并执行解析逻辑。

package com.dependency.demo;

import com.fasterxml.jackson.databind.DeserializationFeature;
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;

@RestController
public class XmlController {

    @GetMapping("/parse-cpe-list") // 定义一个GET请求路径
    public CpeList parseCpeList() throws XMLStreamException, IOException {
        // 从classpath加载XML文件
        InputStream xmlResource = XmlController.class.getClassLoader().getResourceAsStream("test.xml");
        if (xmlResource == null) {
            throw new IOException("XML file 'test.xml' not found in classpath.");
        }

        // 创建XMLStreamReader
        XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlResource);

        // 创建XmlMapper实例
        XmlMapper mapper = new XmlMapper();
        // 可选:配置DeserializationFeature,例如如果XML中有未知字段不报错
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 执行反序列化
        CpeList cpeList = mapper.readValue(xmlStreamReader, CpeList.class);

        // 打印解析结果以验证
        System.out.println("解析到的CPE列表:");
        if (cpeList != null && cpeList.getCpeItems() != null) {
            for (CpeItem cpeItem : cpeList.getCpeItems()) {
                System.out.println("  Name: " + cpeItem.getName() + ", Title: " + cpeItem.getTitle());
            }
        } else {
            System.out.println("  列表为空或解析失败。");
        }

        // 关闭资源
        xmlStreamReader.close();
        xmlResource.close();

        return cpeList;
    }
}
  • @RestController: 标记这是一个Spring MVC控制器,并自动将返回值序列化为响应体。
  • @GetMapping("/parse-cpe-list"): 定义一个HTTP GET请求的端点。
  • getResourceAsStream("test.xml"): 从应用的classpath加载名为test.xml的文件。请确保test.xml文件放在src/main/resources目录下。
  • XMLInputFactory和XMLStreamReader: Jackson内部使用StAX(Streaming API for XML)进行流式解析,这里我们手动创建XMLStreamReader以更灵活地处理输入流。
  • XmlMapper: Jackson XML模块的核心类,用于XML和Java对象之间的序列化/反序列化。
  • mapper.readValue(xmlStreamReader, CpeList.class): 执行反序列化操作,将XML流解析为CpeList对象。
  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES: 这是一个有用的配置,当XML中存在Java对象中没有定义的字段时,不会抛出异常。

4. 完整的XML文件 (test.xml)

将以下内容保存到src/main/resources/test.xml:



    
        xmlread
    
    
        testtitle
    
    
        another_title
    

5. 运行与验证

启动Spring Boot应用,并通过浏览器或Postman访问 http://localhost:8080/parse-cpe-list。

预期输出:

在控制台,您将看到类似以下内容的日志:

解析到的CPE列表:
  Name: John, Title: xmlread
  Name: Jack, Title: testtitle
  Name: Jane, Title: another_title

HTTP响应体将是:


    
        xmlread
    
    
        testtitle
    
    
        another_title
    

这表明所有元素都被成功解析并存储在CpeList对象的cpeItems列表中。

6. 注意事项与总结

  • Jackson注解的精确匹配: 确保Java POJO的字段名、注解中的localName和isAttribute属性与XML结构严格匹配。这是成功解析的关键。
  • @JacksonXmlElementWrapper 的 useWrapping: 当XML中的列表元素直接是父元素的子元素,而没有额外的包装元素时,务必将useWrapping设置为false。这是处理扁平列表结构的关键。
  • 错误处理: 在实际应用中,应加入更健壮的错误处理机制,例如捕获IOException和XMLStreamException,并提供有意义的错误响应。
  • 性能考量: 对于非常大的XML文件,流式解析(如Jackson内部使用的StAX)通常比DOM解析更高效,因为它不需要将整个文档加载到内存中。
  • Lombok: 使用Lombok可以大大简化POJO的代码,减少样板代码,但请确保项目中已添加Lombok依赖。

通过本文的详细指导和示例,您应该能够熟练地使用Jackson在Spring Boot中解析包含重复元素的XML文件,避免只解析到最后一个元素的常见陷阱。理解@JacksonXmlElementWrapper和@JacksonXmlProperty的正确用法是掌握Jackson XML解析能力的重要一步。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

779

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

722

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

727

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

394

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

444

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16860

2023.08.03

excel制作动态图表教程
excel制作动态图表教程

本专题整合了excel制作动态图表相关教程,阅读专题下面的文章了解更多详细教程。

30

2025.12.29

热门下载

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

精品课程

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

共23课时 | 2.1万人学习

C# 教程
C# 教程

共94课时 | 5.6万人学习

Java 教程
Java 教程

共578课时 | 39.3万人学习

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

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