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

- 核心概念:
dom4j是如何工作的? - 详细步骤:如何一步步实现转换。
- 完整代码示例:从 Java 对象到 XML 文件的完整流程。
- 高级配置:如何处理 XML 注解、命名空间等。
核心概念
dom4j 本身是一个用于读写 XML 的强大 API,它并不直接内置“Java 对象转 XML”的功能,这个功能通常通过一个“编组器”(Marshaller)来实现。
在 Java 生态中,最主流的、与 dom4j 兼容的编组器是 JAXB (Java Architecture for XML Binding),JAXB 是 Java 标准库的一部分(从 Java 6 开始),它通过注解来定义 Java 对象和 XML 元素/属性之间的映射关系。
我们的工作流程是:
- 准备 Java 对象:在 Java 对象的字段/方法上添加 JAXB 注解。
- 创建
JAXBContext:这是 JAXB 的入口,用于管理与特定类集相关的 XML/Java 绑定信息。 - 创建
Marshaller:Marshaller是执行转换的核心对象,它负责将 Java 对树转换为 XML 表示。 - 执行转换:调用
marshaller.marshal()方法,传入 Java 对象和输出目标(如文件、控制台等)。
详细步骤
步骤 1:添加 Maven 依赖
确保你的项目中包含 dom4j 和 jaxb-api 的依赖。jaxb-impl 通常包含在 JDK 中,但如果你使用较新的 JDK (如 11+),可能需要显式添加。

<!-- 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 类:

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:运行并查看结果
运行 ObjectToXmlConverter 的 main 方法后,你会在项目根目录下找到 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 需要使用命名空间,可以通过以下方式配置:
-
在
@XmlRootElement中定义命名空间:@XmlRootElement(name = "users", namespace = "http://www.example.com/users")
-
在
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 文档了。
