JAXB 开发详解

摘要

本文主要通过对比使用 JAXB 和非 JAXB 进行 Java 对象转 XML 和 XML 转 Java 对象的方式来介绍 JAXB 的基本功能,让大家对 JAXB 有一个初步的体会。

考虑有如下这样两个 Class、Person 和 Address,其中 Person 持有一个 Address 的引用。

public class Person {
    private Integer id;
    private String name;
    private Integer age;
    private Address address;

    public Integer getId() {
       return id;

    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

public class Address {
    private Integer id;
    private String province;
    private String city;
    private String area;
    private String other;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public String getOther() {
        return other;
    }

    public void setOther(String other) {
        this.other = other;
    }
}

Java 对象转 XML

假设现在需要把一个 Person 类型的对象生成如下格式的 XML:

<person id="1" name="张三">
    <address id="1">
        <area>南山区</area>
        <city>深圳市</city>
        <other>其它</other>
        <province>广东省</province>
    </address>
    <age>30</age>
</person>
基于 DOM 实现

在没有使用 JAXB 之前,比如使用 Dom 生成 XML 的方式,得如下编程:

@Test
public void geneByDom() throws Exception {
    Person person = this.buildPerson();
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
    DocumentBuilder db = factory.newDocumentBuilder();  
    Document document = db.newDocument();  
    Element personEle = document.createElement("person");  
    personEle.setAttribute("id", person.getId().toString());
    personEle.setAttribute("name", person.getName());
    Element ageEle = document.createElement("age");
    ageEle.setTextContent(person.getAge().toString());
    personEle.appendChild(ageEle);
    
    Address address = person.getAddress();
    Element addressEle = document.createElement("address");
    addressEle.setAttribute("id", address.getId().toString());
    Element province = document.createElement("province");
    province.setTextContent(address.getProvince());
    addressEle.appendChild(province);
    
    Element city = document.createElement("city");
    city.setTextContent(address.getCity());
    addressEle.appendChild(city);
    
    Element area = document.createElement("area");
    area.setTextContent(address.getArea());
    addressEle.appendChild(area);
    
    Element other = document.createElement("other");
    other.setTextContent(address.getOther());
    addressEle.appendChild(other);
    
    personEle.appendChild(addressEle);
    document.appendChild(personEle);  
    
    TransformerFactory transformerFactory = TransformerFactory.newInstance();  
    Transformer transformer = transformerFactory.newTransformer();  
    Source xmlSource = new DOMSource(document);  
    //把生成的XML输出到控制台 
    Result outputTarget = new StreamResult(System.out);  
    transformer.transform(xmlSource, outputTarget);  
}
基于 JAXB 实现

基于 JAXB 实现时需要通过 JAXB 提供的注解来控制它的一些行为,比如下面通过在 Person 类上 @XmlRootElement 指定它为一个根节点,对应的根节点名称将默认取类名称,然后首字母小写,在本示例中即取 “person”。通过 @XmlAttribute 指定 id 和 name 作为节点 person的XML 属性,可以通过 XmlAttribute 的 name 属性指定生成的 XML 属性的名称,如 getId() 方法上的 @XmlAttribute(name="id");没有指定 name 属性时对应的 XML 属性名称将使用 Java 属性名称,如 getName() 方法上的 @XmlAttribute。

@XmlRootElement
public class Person {
    private Integer id;
    private String name;
    private Integer age;
    private Address address;

    @XmlAttribute(name = "id")
    public Integer getId() {
       return id;

    }

    public void setId(Integer id) {
        this.id = id;
    }

    @XmlAttribute
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
    
}

public class Address {
    private Integer id;
    private String province;
    private String city;
    private String area;
    private String other;

    @XmlAttribute(name = "id")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public String getOther() {
        return other;
    }

    public void setOther(String other) {
        this.other = other;
    }
}

想要生成目标格式的 XML,基于 Class 的配置就好了。接下来就是调用对应的 API 进行 XML 的转换了。通过如下几行代码就可以把一个 Person 对象生成需要的 XML 格式了。如果还有其他的类型的对象也需要生成 XML,我们只需要把下面代码中的对象和对应的类型更换一下即可,而同样的需求在基于 Dom 的转换中又得重新写一遍代码了,另外从代码层面可以明显的看出基于 JAXB 的方式比基于 DOM 的方式要节约很多代码,实现起来也要简单很多,它的 XML 绑定行为都是通过对应的注解来完成的,非常方便。

@Test
public void testMarshal() throws JAXBException {
    JAXBContext context = JAXBContext.newInstance(Person.class);
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    StringWriter writer = new StringWriter();
    //构造Person对象,不是本文的重点
    Person person = this.buildPerson();

    marshaller.marshal(person, writer);
    System.out.println(writer.toString());
}

JAXB(Java Architecture for XML Binding)是一项可以通过 XML 产生 Java 对象,也可以通过 Java 对象产生 XML 的技术,是 JDK 自带的功能。JDK 中关于 JAXB 部分有几个比较重要的接口或类,如:

  • JAXBContext:它是程序的入口类,提供了 XML/Java 绑定的操作,包括创建 Marshaller 和 Unmarshaller 等。
  • Marshaller:它负责把 Java 对象序列化为对应的 XML。
  • Unmarshaller:它负责把 XML 反序列化为对应的 Java 对象。

使用 JAXB 进行对象转 XML 的基本操作步骤如下:

//1、获取一个基于某个 class 的 JAXBContext,即 JAXB 上下文
JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass());
//2、利用 JAXBContext 对象创建对应的 Marshaller 实例
Marshaller marshaller = jaxbContext.createMarshaller();
//3、设置一些序列化时需要的指定的配置
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
StringWriter writer = new StringWriter();
//4、将对象进行序列化
marshaller.marshal(obj, writer);
  • 创建一个 JAXB 上下文对象,可以传递序列化时需要用到的一些 Class,以便 JAXB 在序列化对应的对象时能够识别其中关联的 Class。
  • 利用 JAXB 上下文对象创建对应的 Marshaller 对象。
  • 指定序列化时的配置参数,具体可以设置的参数和对应的参数的含义可以参考 API 文档。
  • 最后一步是将对应的对象序列化到一个 Writer、OutputStream、File 等输出对象中。

具体内容请参考:http://gitbook.cn/m/mazi/comp/column?columnId=5a210d8a39fa666a31fb0984

上一篇:关于DevExpress VCL汉化方法


下一篇:redis-3.0.6安装