- JAXB (Java Architecture for XML Binding):这是目前最推荐、最标准的方式,从 Java 6 开始,JAXB 就被包含在 Java 标准库中,无需额外依赖,它通过注解将 Java 类和 XML 元素/属性进行绑定。
- XStream:一个第三方库,以其简洁的 API 和强大的功能而闻名,特别是对复杂对象(如包含循环引用的对象)的支持非常好。
- DOM/SAX/StAX 手动解析:这是最底层的方式,通过 W3C 的 DOM API 或 SAX/StAX 解析器手动构建 XML 树,这种方式非常繁琐,不推荐用于简单的对象转 XML,仅在需要精细控制 XML 结构时使用。
下面我将详细介绍最推荐的 JAXB 方式,并简要介绍 XStream 方式。

使用 JAXB (推荐)
JAXB 的核心思想是通过注解来描述 Java 对象如何映射到 XML。
核心步骤
- 准备 Java 对象类:为需要转换的 Java 类添加 JAXB 注解。
- 创建
JAXBContext:这是 JAXB 的入口,用于管理到特定 Java 类/包的 XML/Java 绑定信息。 - 创建
Marshaller:Marshaller是将 Java 对树转换为 XML 的核心组件。 - 执行转换:调用
marshaller.marshal()方法进行转换。
实战示例
假设我们有一个 User 对象,需要将其转换为 XML。
第一步:创建 Java 类 (User.java)
import javax.xml.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
// 定义 XML 的根元素名称
@XmlRootElement(name = "user")
// 定义命名空间,可以省略
@XmlNs(namespace = "http://www.example.com/users")
// 控制 XML 输出的顺序,这里是按字母顺序
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
// 映射为 XML 属性
@XmlAttribute
private int id;
// 映射为 XML 元素
@XmlElement(name = "full_name")
private String name;
// 映射为 XML 元素
private int age;
// 如果某个字段不需要映射到 XML,使用 @XmlTransient
@XmlTransient
private String password;
// 处理集合类型(List, Set等)
@XmlElement(name = "role")
private List<String> roles = new ArrayList<>();
// 必须提供一个无参的构造函数,JAXB需要它来创建实例
public User() {
}
// 带参的构造函数,方便创建对象
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// Getter 和 Setter 方法是必须的
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 int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public List<String> getRoles() { return roles; }
public void setRoles(List<String> roles) { this.roles = roles; }
// 可以添加一个方法来方便地添加角色
public void addRole(String role) {
this.roles.add(role);
}
}
第二步:编写转换代码
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
public class JaxbExample {
public static void main(String[] args) {
// 1. 创建一个 Java 对象
User user = new User(101, "张三", 30);
user.addRole("ADMIN");
user.addRole("DEVELOPER");
user.setPassword("123456"); // 这个字段会被忽略
try {
// 2. 创建 JAXBContext,传入需要转换的类的 Class 对象
JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
// 3. 创建 Marshaller 实例
Marshaller marshaller = jaxbContext.createMarshaller();
// 4. 设置格式化输出(美化 XML)
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 5. 创建一个 StringWriter 来接收转换后的 XML 字符串
StringWriter writer = new StringWriter();
// 6. 执行转换:将 user 对象写入到 writer 中
marshaller.marshal(user, writer);
// 7. 输出结果
String xml = writer.toString();
System.out.println(xml);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
第三步:查看输出结果
运行上述代码,控制台会输出格式化后的 XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user id="101">
<full_name>张三</full_name>
<age>30</age>
<role>ADMIN</role>
<role>DEVELOPER</role>
</user>
常用注解总结:
| 注解 | 作用 | 示例 |
|---|---|---|
@XmlRootElement |
将类映射为 XML 的根元素。 | @XmlRootElement(name = "user") |
@XmlElement |
将字段/属性映射为 XML 元素。 | @XmlElement(name = "full_name") |
@XmlAttribute |
将字段/属性映射为 XML 元素的属性。 | @XmlAttribute |
@XmlTransient |
标记该字段不参与 XML 映射。 | @XmlTransient |
@XmlElementWrapper |
为集合类型生成一个包装元素。 | @XmlElementWrapper(name = "roles") @XmlElement(name = "role") |
@XmlAccessorType |
控制哪些字段/属性会被映射。FIELD表示所有字段,PROPERTY表示所有属性的getter/setter。 |
@XmlAccessorType(XmlAccessType.FIELD) |
使用 XStream (第三方库)
XStream 非常简洁,通常不需要注解,它可以根据类的结构和字段名自动生成 XML。
添加依赖
如果你使用 Maven,在 pom.xml 中添加:
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.20</version> <!-- 请使用最新版本 -->
</dependency>
实战示例
第一步:使用和 JAXB 相同的 User.java 类(可以去掉 JAXB 注解)
// User.java (无需 JAXB 注解)
public class User {
private int id;
private String name;
private int age;
private String password;
private List<String> roles = new ArrayList<>();
// ... (无参构造函数, getter, setter, addRole 方法) ...
}
第二步:编写转换代码
import com.thoughtworks.xstream.XStream;
import java.util.ArrayList;
import java.util.List;
public class XStreamExample {
public static void main(String[] args) {
// 1. 创建 XStream 实例
XStream xstream = new XStream();
// 2. (可选) 设置别名,简化 XML 路径
// 将 User 类映射为 "user" 节点
xstream.alias("user", User.class);
// 将 List<String> 映射为 "roles" 节点
xstream.aliasField("roles", User.class, "roles");
// 将 String 类型在 roles 列表中的元素映射为 "role" 节点
xstream.alias("role", String.class);
// 3. 创建 Java 对象
User user = new User(101, "张三", 30);
user.addRole("ADMIN");
user.addRole("DEVELOPER");
// 4. 执行转换:toXML() 方法直接返回 XML 字符串
String xml = xstream.toXML(user);
// 5. 输出结果
System.out.println(xml);
}
}
第三步:查看输出结果
<user>
<id>101</id>
<name>张三</name>
<age>30</age>
<roles>
<role>ADMIN</role>
<role>DEVELOPER</role>
</roles>
</user>
XStream 的优点是代码量少,但灵活性不如 JAXB,尤其是在处理复杂命名空间、继承关系时,JAXB 是更好的选择。
总结与对比
| 特性 | JAXB | XStream |
|---|---|---|
| 依赖 | Java 标准库 (JDK 6+),无需额外依赖 | 第三方库 (Maven/Gradle) |
| 易用性 | 需要学习注解,但非常规范 | API 极其简洁,开箱即用 |
| 灵活性 | 高,通过注解可以精细控制 XML 的每一个细节 | 较高,但控制力不如 JAXB |
| 性能 | 性能良好,是标准实现 | 性能通常也很好,但在极端情况下可能不如 JAXB |
| 推荐场景 | 企业级应用、Web 服务、需要严格遵循标准规范的场景 | 快速原型开发、简单的对象序列化任务、追求代码简洁的场景 |
对于绝大多数 Java 项目,强烈推荐使用 JAXB,它是 Java 生态的一部分,稳定、可靠、文档丰富,并且得到了广泛的支持,只有在项目有特殊限制(如不能使用 Java 6+)或者追求极致的代码简洁性时,才考虑使用 XStream。
