- JAXB (Java Architecture for XML Binding) - Java 标准内置,非常流行且易于使用。
- Jackson with XML Extension - 性能极佳,是许多现代 Web 服务的首选。
- DOM/SAX 解析 - 底层 API,最灵活但代码也最繁琐,适用于复杂或非标准的 XML 处理。
准备工作:定义 XML 和 Java 对象
为了演示,我们首先定义一个简单的 XML 结构和与之对应的 Java 类。

示例 XML (user.xml):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
<id>101</id>
<name>张三</name>
<email>zhangsan@example.com</email>
<roles>
<role>ADMIN</role>
<role>USER</role>
</roles>
</user>
使用 JAXB (推荐)
JAXB 从 Java 6 开始就是标准库的一部分,无需额外依赖,它通过注解将 XML 元素与 Java 对象的字段绑定。
创建 Java 类
import javax.xml.bind.annotation.*;
import java.util.List;
// 根节点 <user> 对应 User 类
@XmlRootElement(name = "user")
// 控制序列化/反序列化时是否输出字段名(如 <id> 而不是 <User_id>)
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
// <id> 标签对应 id 字段
@XmlElement(name = "id")
private int id;
// <name> 标签对应 name 字段
@XmlElement(name = "name")
private String name;
// <email> 标签对应 email 字段
@XmlElement(name = "email")
private String email;
// <roles> 标签对应 roles 字段
@XmlElement(name = "role") // 指定列表中每个元素的标签名
private List<String> roles;
// 必须提供一个无参构造函数,JAXB 内部会使用它
public User() {
}
// Getters and Setters (标准 JavaBean 规范)
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; }
public List<String> getRoles() { return roles; }
public void setRoles(List<String> roles) { this.roles = roles; }
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", roles=" + roles +
'}';
}
}
编写转换代码
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.Marshaller;
import java.io.File;
public class JaxbExample {
public static void main(String[] args) {
// --- XML 文件路径 ---
File xmlFile = new File("user.xml");
try {
// 1. 创建 JAXBContext,传入需要绑定的类
JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
// 2. 创建 Unmarshaller(用于将 XML 转为对象)
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
// 3. 执行 unmarshal 操作,将 XML 文件转换为 User 对象
// unmarshal() 方法返回的是 Object,需要强制类型转换
User user = (User) jaxbUnmarshaller.unmarshal(xmlFile);
// 4. 打印结果
System.out.println("JAXB 解析成功!");
System.out.println(user);
// --- (可选) 对象转回 XML ---
System.out.println("\n--- 将对象转回 XML ---");
Marshaller marshaller = jaxbContext.createMarshaller();
// 格式化输出,使 XML 更易读
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 输出到控制台
marshaller.marshal(user, System.out);
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果
JAXB 解析成功!
User{id=101, name='张三', email='zhangsan@example.com', roles=[ADMIN, USER]}
--- 将对象转回 XML ---
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
<id>101</id>
<name>张三</name>
<email>zhangsan@example.com</email>
<role>ADMIN</role>
<role>USER</role>
</user>
使用 Jackson with XML Extension
Jackson 是一个非常流行的 JSON 库,但它也支持 XML,它通常被认为比 JAXB 性能更好,并且是 Spring Boot 等框架的默认选择。
添加 Maven 依赖
你需要在你的 pom.xml 文件中添加 Jackson 的 XML 模块依赖。

<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.15.2</version> <!-- 使用最新版本 -->
</dependency>
创建 Java 类
Jackson 的注解与 JAXB 类似,但有一些细微差别。@JacksonXmlProperty 是其核心注解之一。
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 java.util.List;
// 指定根元素的名称和命名空间
@JacksonXmlRootElement(localName = "user")
public class UserJackson {
// localName 指定 XML 中的标签名
@JacksonXmlProperty(localName = "id")
private int id;
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlProperty(localName = "email")
private String email;
// @JacksonXmlElementWrapper 用于包装集合元素,可以指定包装标签的名称
@JacksonXmlElementWrapper(localName = "roles")
// @JacksonXmlProperty 指定集合中每个元素的标签名
@JacksonXmlProperty(localName = "role")
private List<String> roles;
public UserJackson() {
}
// 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; }
public List<String> getRoles() { return roles; }
public void setRoles(List<String> roles) { this.roles = roles; }
@Override
public String toString() {
return "UserJackson{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", roles=" + roles +
'}';
}
}
编写转换代码
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.File;
import java.io.IOException;
public class JacksonExample {
public static void main(String[] args) {
File xmlFile = new File("user.xml");
try {
// 1. 创建 XmlMapper,这是 Jackson 处理 XML 的核心类
XmlMapper xmlMapper = new XmlMapper();
// 2. 使用 readValue 方法直接将文件内容读取到对象中
UserJackson user = xmlMapper.readValue(xmlFile, UserJackson.class);
// 3. 打印结果
System.out.println("Jackson 解析成功!");
System.out.println(user);
// --- (可选) 对象转回 XML ---
System.out.println("\n--- 将对象转回 XML ---");
String xmlOutput = xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
System.out.println(xmlOutput);
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果
与方法一类似,输出一个 UserJackson 对象和格式化的 XML 字符串。
使用 DOM (文档对象模型) 解析
这是最底层的 API,它将整个 XML 文档读入内存,构建一个树形结构(DOM Tree),然后你可以在树中导航来查找和修改数据。
编写转换代码
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.File;
public class DomExample {
public static void main(String[] args) {
File xmlFile = new File("user.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
// 1. 创建 DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// 2. 解析 XML 文件,创建 Document 对象(DOM 树的根)
Document document = builder.parse(xmlFile);
// 3. 获取根元素 <user>
Element userElement = document.getDocumentElement();
// 4. 创建一个简单的 Java 对象来存储数据
User user = new User(); // 假设我们复用方法一中的 User 类
// 5. 通过标签名获取子元素,并获取其文本内容
NodeList idList = userElement.getElementsByTagName("id");
if (idList.getLength() > 0) {
user.setId(Integer.parseInt(idList.item(0).getTextContent()));
}
NodeList nameList = userElement.getElementsByTagName("name");
if (nameList.getLength() > 0) {
user.setName(nameList.item(0).getTextContent());
}
NodeList emailList = userElement.getElementsByTagName("email");
if (emailList.getLength() > 0) {
user.setEmail(emailList.item(0).getTextContent());
}
// 6. 处理列表 <roles>
NodeList roleList = userElement.getElementsByTagName("role");
for (int i = 0; i < roleList.getLength(); i++) {
Node roleNode = roleList.item(i);
if (roleNode.getNodeType() == Node.ELEMENT_NODE) {
Element roleElement = (Element) roleNode;
// 这里需要手动维护一个列表,非常繁琐
// 简化示例,只取第一个 role
user.getRoles().add(roleElement.getTextContent());
break;
}
}
// 实际项目中,处理列表需要更复杂的代码来循环和添加
// 7. 打印结果
System.out.println("DOM 解析成功!");
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}
}
}
总结与对比
| 特性 | JAXB | Jackson (XML) | DOM/SAX |
|---|---|---|---|
| 易用性 | 非常高,注解清晰,代码简洁 | 高,API 简洁,类似 Jackson JSON | 低,需要大量手动操作,代码冗长 |
| 性能 | 良好 | 非常高,通常优于 JAXB | DOM: 加载整个文档到内存,大文件时性能差、耗内存 SAX: 流式解析,内存占用小,速度快 |
| 依赖 | Java 标准库 (JDK 6+),无需额外依赖 | 需要添加 jackson-dataformat-xml 依赖 |
Java 标准库 (JDK 1+),无需额外依赖 |
| 灵活性 | 适用于标准的、结构化的 XML | 适用于标准的、结构化的 XML,且支持复杂配置 | 极高,可以处理任何格式的 XML,包括非结构化的 |
| 主要用途 | Web 服务 (SOAP, JAX-WS),配置文件 | RESTful Web 服务 (支持 JSON/XML),高性能应用 | 复杂的 XML 解析任务,需要精细控制或处理“畸形”XML |
| 学习曲线 | 低 | 低 | 高 |
如何选择?
- 如果你在开发一个标准的 Java 应用(非 Web 服务),并且希望使用最简单、最直接的方式:JAXB 是最佳选择,它无需任何外部依赖,且非常稳定。
- 如果你在开发一个现代的 RESTful API,或者对性能有极高要求,或者项目已经在使用 Jackson 处理 JSON:Jackson with XML 是不二之选,它在性能和易用性之间取得了很好的平衡。
- 如果你需要处理一个非常巨大(GB 级别)的 XML 文件,或者 XML 结构非常不规则、复杂,甚至格式有些问题:你应该考虑 SAX 解析器,因为它不会将整个文件加载到内存中,如果需要随机访问或修改 XML 的任何部分,DOM 是唯一的选择,但要准备好处理其内存消耗和复杂性。
对于绝大多数日常开发任务,JAXB 和 Jackson 是更优、更现代的选择。

