核心挑战
在转换之前,需要了解 XML 和 JSON 在结构上的主要区别,因为转换并非总是 1:1 的:

- 属性 vs. 键值对: XML 元素有属性和子元素,而 JSON 只有键值对,转换时,通常需要决定是将属性作为 JSON 对象的一个字段,还是忽略。
- 数组 vs. 单一对象: XML 中有多个同名兄弟节点,它们应该被转换为一个 JSON 数组,如果只有一个,它通常是一个 JSON 对象,有些库可以自动处理,有些则需要手动配置。
- CDATA 和特殊字符: XML 中的
<![CDATA[...]]>和特殊字符(如<,>,&)需要在 JSON 中正确转义。 - 命名空间: XML 命名空间在 JSON 中通常被保留或以特定方式处理。
使用 Jackson (推荐)
Jackson 是一个非常流行和强大的 Java JSON 库,它通过 jackson-dataformat-xml 模块也支持 XML,这是目前最推荐的方法,因为它高效、灵活,并且是许多大型项目(如 Spring Boot)的首选。
添加 Maven 依赖
在你的 pom.xml 文件中添加 Jackson 的 XML 和核心模块依赖:
<dependencies>
<!-- Jackson 核心库 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version> <!-- 使用最新版本 -->
</dependency>
<!-- Jackson XML 处理模块 -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.15.2</version> <!-- 版本与核心库保持一致 -->
</dependency>
</dependencies>
准备 XML 和 Java 类 (POJO)
为了进行转换,Jackson 需要将 XML 映射到 Java 对象,你需要根据你的 XML 结构创建对应的 Plain Old Java Object (POJO)。
示例 XML (user.xml):

<user>
<name>John Doe</name>
<age>30</age>
<email>john.doe@example.com</email>
<address>
<street>123 Main St</street>
<city>Anytown</city>
</address>
<skills>
<skill>Java</skill>
<skill>Spring</skill>
<skill>SQL</skill>
</skills>
</user>
对应的 Java 类:
// Address.java
public class Address {
private String street;
private String city;
// Getters and Setters (必须要有)
public String getStreet() { return street; }
public void setStreet(String street) { this.street = street; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
// (可选) 为了打印方便,添加 toString()
@Override
public String toString() {
return "Address{" + "street='" + street + '\'' + ", city='" + city + '\'' + '}';
}
}
// Skill.java - skills 是一个列表
// Jackson可以直接处理List<String>,所以这个类可能不需要
// 但如果skill有属性,就需要定义
// User.java
import java.util.List;
public class User {
private String name;
private int age;
private String email;
private Address address;
private List<String> skills;
// Getters and Setters (必须要有)
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 getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Address getAddress() { return address; }
public void setAddress(Address address) { this.address = address; }
public List<String> getSkills() { return skills; }
public void setSkills(List<String> skills) { this.skills = skills; }
@Override
public String toString() {
return "User{" + "name='" + name + '\'' + ", age=" + age + ", email='" + email + '\'' + ", address=" + address + ", skills=" + skills + '}';
}
}
编写转换代码
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.File;
import java.io.IOException;
public class JacksonXmlToJsonConverter {
public static void main(String[] args) {
try {
// 1. 创建 XmlMapper 实例
XmlMapper xmlMapper = new XmlMapper();
// 2. 读取 XML 文件并转换为 Java 对象
User user = xmlMapper.readValue(new File("user.xml"), User.class);
// 3. 创建普通的 ObjectMapper 实例
ObjectMapper jsonMapper = new ObjectMapper();
// 4. 将 Java 对象转换为 JSON 字符串
// 使用 .writerWithDefaultPrettyPrinter() 使 JSON 输出格式化,更易读
String jsonString = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
// 5. 输出 JSON
System.out.println(jsonString);
// (可选) 将 JSON 写入文件
// jsonMapper.writeValue(new File("user.json"), user);
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果 (user.json):
{
"name" : "John Doe",
"age" : 30,
"email" : "john.doe@example.com",
"address" : {
"street" : "123 Main St",
"city" : "Anytown"
},
"skills" : [ "Java", "Spring", "SQL" ]
}
使用 XStream
XStream 是另一个非常成熟的库,专门用于在 Java 对象和 XML 之间进行序列化/反序列化,它也可以配置为输出 JSON。
添加 Maven 依赖
<dependencies>
<!-- XStream Core -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.20</version> <!-- 使用最新版本 -->
</dependency>
<!-- XStream JSON Converter -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream-json-lib</artifactId>
<version>1.4.20</version>
</dependency>
</dependencies>
编写转换代码
XStream 的优点是无需创建严格的 POJO,可以使用 Map 或直接处理,但为了与 Jackson 示例对比,我们使用相同的 User 类。
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class XStreamXmlToJsonConverter {
public static void main(String[] args) {
try {
// 1. 读取 XML 文件内容
String xml = new String(Files.readAllBytes(new File("user.xml").toPath()));
// 2. 创建 XStream 实例,并配置为使用 JSON 驱动
XStream xstream = new XStream(new JettisonMappedXmlDriver());
// 3. (可选) 设置更美观的输出格式
xstream.setMode(XStream.NO_REFERENCES); // 避免循环引用
// xstream.toXML(System.out, new FileWriter("user.json")); // 直接写入文件
// 4. 直接将 XML 字符串转换为 JSON 字符串
String json = xstream.toXML(xml);
// 5. 输出 JSON
System.out.println(json);
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果:
XStream 默认的 JSON 输出格式与 Jackson 略有不同,且默认不进行美化,输出可能是一行:
{"user":{"name":"John Doe","age":30,"email":"john.doe@example.com","address":{"street":"123 Main St","city":"Anytown"},"skills":["Java","Spring","SQL"]}}
使用 org.json (简单库)
这是一个非常轻量级的库,适合简单的转换任务,它不依赖复杂的映射,而是让你手动解析。
添加 Maven 依赖
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20251013</version> <!-- 使用最新版本 -->
</dependency>
</dependencies>
编写转换代码
这种方法需要你手动解析 XML 并构建 org.json.JSONObject 和 org.json.JSONArray,代码量较多,灵活性差,不推荐用于复杂的 XML。
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.XML;
import java.io.File;
import java.nio.file.Files;
public class OrgJsonConverter {
public static void main(String[] args) {
try {
// 1. 读取 XML 文件内容
String xml = new String(Files.readAllBytes(new File("user.xml").toPath()));
// 2. 使用 org.json 库的静态方法直接转换
// options() 方法可以配置转换行为,例如是否保留命名空间
JSONObject jsonObject = XML.toJSONObject(xml);
// 3. 将 JSONObject 转换为格式化的 JSON 字符串
String jsonString = jsonObject.toString(2); // 2 是缩进空格数
// 4. 输出 JSON
System.out.println(jsonString);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果:
{
"user": {
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"address": {
"street": "123 Main St",
"city": "Anytown"
},
"skills": {
"skill": [
"Java",
"Spring",
"SQL"
]
}
}
}
注意,org.json 将 <skills> 标签下的同名 <skill> 转换为了一个包含数组的对象 {"skill": [...]},而不是直接变成 {"skills": [...]},这是它的一个特点。
总结与推荐
| 特性 | Jackson | XStream | org.json |
|---|---|---|---|
| 易用性 | 中等 (需要定义POJO) | 高 (可处理Map/动态对象) | 高 (一行代码转换) |
| 灵活性 | 极高 (丰富的配置选项) | 高 (注解、转换器) | 低 (简单场景) |
| 性能 | 高 | 中等 | 中等 |
| 功能 | 全面 (JSON, XML, YAML, CSV等) | 强大 (XML为主,可扩展) | 简单 (仅JSON/XML) |
| 适用场景 | 大型项目、复杂对象映射、高性能需求 | 需要灵活处理XML、有特殊转换需求 | 快速原型、简单XML、轻量级需求 |
| 依赖 | jackson-databind, jackson-dataformat-xml |
xstream, xstream-json-lib |
json |
最终建议
- 对于绝大多数 Java 项目,特别是企业级应用和 Web 服务(如 Spring Boot),强烈推荐使用 Jackson。 它是事实上的标准,性能卓越,功能强大,社区支持好。
- 如果你的 XML 结构非常动态,或者你希望用最少的代码快速实现一个转换,并且不介意性能不是最优,可以考虑 XStream。
- 如果你只需要一个非常简单的、一次性的转换,并且不想引入过多的依赖,org.json 是一个不错的选择,但要小心它的输出格式可能不完全符合你的预期。
