杰瑞科技汇

Java XML 如何转 JSON?

核心挑战

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

Java XML 如何转 JSON?-图1
(图片来源网络,侵删)
  1. 属性 vs. 键值对: XML 元素有属性和子元素,而 JSON 只有键值对,转换时,通常需要决定是将属性作为 JSON 对象的一个字段,还是忽略。
  2. 数组 vs. 单一对象: XML 中有多个同名兄弟节点,它们应该被转换为一个 JSON 数组,如果只有一个,它通常是一个 JSON 对象,有些库可以自动处理,有些则需要手动配置。
  3. CDATA 和特殊字符: XML 中的 <![CDATA[...]]> 和特殊字符(如 <, >, &)需要在 JSON 中正确转义。
  4. 命名空间: 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):

Java XML 如何转 JSON?-图2
(图片来源网络,侵删)
<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.JSONObjectorg.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 是一个不错的选择,但要小心它的输出格式可能不完全符合你的预期。
分享:
扫描分享到社交APP
上一篇
下一篇