JAXB XML对象绑定

JAXB(Java Architecture for XML Binding)是通过注解实现Java实体类和XML映射的标准API。通过JAXB我们能够很容易的实现Java实体类对象序列化为XML以及XML反序列化为Java实体类对象。

注意:随着时间的推移JAXB被从JDK11移出,因为它属于JavaEE规范,但你仍可以通过Maven引入该依赖。

XML类型和Java类型的映射关系

XML类型和Java类型之间具有一定的映射关系,具体见下表。

Java-XML绑定注解

这里我们编写一个简单的例子演示JAXB的用法。下面代码是一个Java实体类,其中使用JAXB注解定义了JavaBean和XML之间的映射关系。

User.java

package com.gacfox.demo.model;

import javax.xml.bind.annotation.*;
import java.util.Date;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "user")
@XmlType(name = "user", propOrder = {"name", "age", "birthday"})
public class User {
    @XmlAttribute
    private long id;
    @XmlElement
    private String name;
    @XmlElement
    private int age;
    @XmlElement
    private Date birthday;

    public long getId() {
        return id;
    }

    public void setId(long 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 Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

代码中我们用到的注解如下:

  • @XmlAccessorType:类级别注解,XmlAccessorType.FIELD表示映射所有非静态属性
  • @XmlRootElement:类级别注解,用于指定XML根节点的名字
  • @XmlType:类级别注解,name是这个约束的名字没什么实际意义,propOrder是XML中所有子节点的顺序
  • @XmlAttribute:属性级别注解,用于指定该属性为根节点的XML属性
  • @XmlElement:属性级别注解,用于指定该属性为XML节点

如何给子节点添加属性?这可能涉及到复杂类型的映射问题(上面除了能直接映射的Date都是基本类型),给子节点加属性就需要把子节点单独定义成一个新类,@XmlElement只能给当前类的根节点加上属性。

注意:XML文档设计中,一个值应该作为文本节点还是作为一个节点的属性,这需要一定的设计经验,具体可以参考XML相关章节。

基于XML的序列化和反序列化

下面代码中,我们编写了User类序列化为XML以及从XML反序列化为Java对象的例子代码。

Main.java

package com.gacfox.demo;

import com.gacfox.demo.model.User;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.util.Date;

public class Main {
    public static void main(String[] args) throws Exception {
        writeXml();
        readXml();
    }

    public static void writeXml() throws Exception {
        //创建User对象
        User user = new User();
        user.setId(1);
        user.setName("tom");
        user.setAge(10);
        user.setBirthday(new Date());

        File file = new File("test.xml");
        //获取JAXB上下文,获取序列化器
        JAXBContext context = JAXBContext.newInstance(User.class);
        Marshaller marshaller = context.createMarshaller();
        //设置格式化输出
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(user, file);
    }

    public static void readXml() throws Exception {
        File file = new File("test.xml");
        JAXBContext context = JAXBContext.newInstance(User.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        User user = (User) unmarshaller.unmarshal(file);
        System.out.println(user);
    }
}

输出的XML文档如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user id="1">
    <name>tom</name>
    <age>10</age>
    <birthday>2017-11-10T22:54:16.785+08:00</birthday>
</user>
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。