杰瑞科技汇

Java对象如何高效转XML?

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

下面我将详细介绍最推荐的 JAXB 方式,并简要介绍 XStream 方式。

Java对象如何高效转XML?-图1
(图片来源网络,侵删)

使用 JAXB (推荐)

JAXB 的核心思想是通过注解来描述 Java 对象如何映射到 XML。

核心步骤

  1. 准备 Java 对象类:为需要转换的 Java 类添加 JAXB 注解。
  2. 创建 JAXBContext:这是 JAXB 的入口,用于管理到特定 Java 类/包的 XML/Java 绑定信息。
  3. 创建 MarshallerMarshaller 是将 Java 对树转换为 XML 的核心组件。
  4. 执行转换:调用 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。

分享:
扫描分享到社交APP
上一篇
下一篇