杰瑞科技汇

dom4j如何将Java对象转为XML?

下面我将为你提供一个完整、详细的指南,包括:

dom4j如何将Java对象转为XML?-图1
(图片来源网络,侵删)
  1. 核心概念dom4j 是如何工作的?
  2. 详细步骤:如何一步步实现转换。
  3. 完整代码示例:从 Java 对象到 XML 文件的完整流程。
  4. 高级配置:如何处理 XML 注解、命名空间等。

核心概念

dom4j 本身是一个用于读写 XML 的强大 API,它并不直接内置“Java 对象转 XML”的功能,这个功能通常通过一个“编组器”(Marshaller)来实现。

在 Java 生态中,最主流的、与 dom4j 兼容的编组器是 JAXB (Java Architecture for XML Binding),JAXB 是 Java 标准库的一部分(从 Java 6 开始),它通过注解来定义 Java 对象和 XML 元素/属性之间的映射关系。

我们的工作流程是:

  1. 准备 Java 对象:在 Java 对象的字段/方法上添加 JAXB 注解。
  2. 创建 JAXBContext:这是 JAXB 的入口,用于管理与特定类集相关的 XML/Java 绑定信息。
  3. 创建 MarshallerMarshaller 是执行转换的核心对象,它负责将 Java 对树转换为 XML 表示。
  4. 执行转换:调用 marshaller.marshal() 方法,传入 Java 对象和输出目标(如文件、控制台等)。

详细步骤

步骤 1:添加 Maven 依赖

确保你的项目中包含 dom4jjaxb-api 的依赖。jaxb-impl 通常包含在 JDK 中,但如果你使用较新的 JDK (如 11+),可能需要显式添加。

dom4j如何将Java对象转为XML?-图2
(图片来源网络,侵删)
<!-- pom.xml -->
<dependencies>
    <!-- dom4j 核心库 -->
    <dependency>
        <groupId>org.dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>2.1.4</version>
    </dependency>
    <!-- JAXB API (用于注解) -->
    <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
        <version>4.0.0</version>
    </dependency>
    <!-- JAXB 实现 (JDK 11+ 需要手动添加) -->
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>4.0.2</version>
    </dependency>
</dependencies>

注意:如果你使用的是 Java 8 或更早版本,jakarta.xml.bind-api 应该是 javax.xml.bind:jaxb-api

步骤 2:创建 Java 对象(POJO)并添加 JAXB 注解

这是最关键的一步,我们通过注解来告诉 JAXB 如何将我们的 Java 类映射到 XML。

假设我们要表示一个用户列表:

import jakarta.xml.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
// 1. @XmlRootElement: 定义 XML 的根元素名称
@XmlRootElement(name = "users")
// 2. @XmlAccessorType: 指定哪些字段/属性需要被映射。
//    FIELD 表示所有非 static、非 transient 的字段都会被映射。
@XmlAccessorType(XmlAccessType.FIELD)
public class UserList {
    // 3. @XmlElement: 定义一个 XML 元素
    @XmlElement(name = "user")
    private List<User> users = new ArrayList<>();
    // 无参构造函数是必须的,以便 JAXB 可以实例化该对象
    public UserList() {
    }
    // 添加用户的便捷方法
    public void addUser(User user) {
        users.add(user);
    }
    // Getter 和 Setter
    public List<User> getUsers() {
        return users;
    }
    public void setUsers(List<User> users) {
        this.users = users;
    }
}

再创建 User 类:

dom4j如何将Java对象转为XML?-图3
(图片来源网络,侵删)
import jakarta.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
    // 4. @XmlAttribute: 定义一个 XML 属性
    @XmlAttribute
    private int id;
    @XmlElement
    private String name;
    @XmlElement
    private String email;
    // 无参构造函数
    public User() {
    }
    // 全参构造函数
    public User(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
    // Getters and Setters...
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

步骤 3:编写转换代码

我们创建一个主类来执行转换逻辑。

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import java.io.File;
public class ObjectToXmlConverter {
    public static void main(String[] args) {
        // 1. 创建要转换的 Java 对象
        UserList userList = new UserList();
        userList.addUser(new User(1, "张三", "zhangsan@example.com"));
        userList.addUser(new User(2, "李四", "lisi@example.com"));
        userList.addUser(new User(3, "王五", "wangwu@example.com"));
        // 2. 定义输出的 XML 文件路径
        File xmlFile = new File("users.xml");
        try {
            // 3. 创建 JAXBContext 实例
            //    参数是包含 @XmlRootElement 等注解的类的 Class 对象
            JAXBContext jaxbContext = JAXBContext.newInstance(UserList.class);
            // 4. 创建 Marshaller 实例
            Marshaller marshaller = jaxbContext.createMarshaller();
            // 5. 配置 Marshaller
            //    格式化输出,使 XML 文件更易读
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            // 6. 执行转换(将 Java 对象写入 XML 文件)
            //    marshaller.marshal(javaObject, outputStream);
            marshaller.marshal(userList, xmlFile);
            System.out.println("Java 对象已成功转换为 XML 文件:" + xmlFile.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

步骤 4:运行并查看结果

运行 ObjectToXmlConvertermain 方法后,你会在项目根目录下找到 users.xml 文件,其内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<users>
    <user id="1">
        <name>张三</name>
        <email>zhangsan@example.com</email>
    </user>
    <user id="2">
        <name>李四</name>
        <email>lisi@example.com</email>
    </user>
    <user id="3">
        <name>王五</name>
        <email>wangwu@example.com</email>
    </user>
</users>

完整代码示例

将以上所有部分整合在一起:

User.java

package com.example.pojo;
import jakarta.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
    @XmlAttribute
    private int id;
    @XmlElement
    private String name;
    @XmlElement
    private String email;
    public User() {}
    public User(int id, String name, String email) {
        this.id = id; this.name = name; this.email = email;
    }
    // Getters and Setters...
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

UserList.java

package com.example.pojo;
import jakarta.xml.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@XmlRootElement(name = "users")
@XmlAccessorType(XmlAccessType.FIELD)
public class UserList {
    @XmlElement(name = "user")
    private List<User> users = new ArrayList<>();
    public UserList() {}
    public void addUser(User user) { users.add(user); }
    public List<User> getUsers() { return users; }
    public void setUsers(List<User> users) { this.users = users; }
}

ObjectToXmlConverter.java

package com.example.converter;
import com.example.pojo.UserList;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import java.io.File;
public class ObjectToXmlConverter {
    public static void main(String[] args) {
        UserList userList = new UserList();
        userList.addUser(new User(1, "张三", "zhangsan@example.com"));
        userList.addUser(new User(2, "李四", "lisi@example.com"));
        File xmlFile = new File("users.xml");
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(UserList.class);
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(userList, xmlFile);
            System.out.println("转换成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

高级配置

输出到控制台

如果你想直接在控制台打印 XML,只需将 File 对象替换为 System.out

// ...
marshaller.marshal(userList, System.out);
// ...

处理命名空间

如果你的 XML 需要使用命名空间,可以通过以下方式配置:

  1. @XmlRootElement 中定义命名空间

    @XmlRootElement(name = "users", namespace = "http://www.example.com/users")
  2. Marshaller 上设置命名空间前缀

    // 创建一个 Map 来存储命名空间和前缀的映射
    Map<String, String> nsMap = new HashMap<>();
    nsMap.put("u", "http://www.example.com/users");
    // 创建一个 QName,包含命名空间和本地名
    marshaller.marshal(userList, new QName("http://www.example.com/users", "users"), System.out);

    更简单的方式是直接在注解中指定,Marshaller 会自动处理。

常用 JAXB 注解总结

注解 作用 示例
@XmlRootElement 定义 XML 文档的根元素。 @XmlRootElement(name = "users")
@XmlElement 将字段映射为 XML 元素。 @XmlElement(name = "userName")
@XmlAttribute 将字段映射为 XML 属性。 @XmlAttribute(name = "id")
@XmlAccessorType 控制哪些字段/属性需要被序列化。 @XmlAccessorType(XmlAccessType.FIELD)
@XmlTransient 标记一个字段,使其被序列化。 @XmlTransient private String tempField;
@XmlElementWrapper 用于包装一个集合类型的元素,生成一个包裹性的父元素。 @XmlElementWrapper(name = "userList")
@XmlElement(name = "user")

通过以上步骤和配置,你就可以灵活地使用 dom4j(配合 JAXB)将任何复杂的 Java 对象结构转换为格式规范的 XML 文档了。

分享:
扫描分享到社交APP
上一篇
下一篇