Java操作XML(8)--JAXB使用


JAXB(Java Architecture for XML Binding)是J2SE和J2EE平台的一部分,能夠快速完成Java類和XML的互相映射。本文主要介紹JAXB的基本使用,文中所使用到的軟件版本:Java 1.8.0_181。

1、JAXB簡介

       JAXB為XML節點和屬性提供提供了各種面向對象的處理方式,可以基於注解或適配器將XML轉換為Java對象。因為其優雅的處理方式,從JRE6開始,JAXB就已經成為了JRE的內置模塊。

1.1、JAXB相關的重要類與接口

JAXBContext類  應用的入口,用於管理XML/Java綁定信息。
Marshaller接口  將Java對象序列化為XML數據。
Unmarshaller接口  將XML數據反序列化為Java對象。

1.2、JAXB注解

1.2.1、@XmlRootElement

類級別注解;將類映射為xml全局元素,也就是根元素。

參數 name  用於指定生成元素的名字,若不指定,默認使用類名小寫作為元素名。
參數 namespace  用於指定生成的元素所屬的命名空間。

@XmlRootElement(name = "class", namespace = "http://www.w3.org/TR/html4/school/")
public class GradeJaxb {
  ...
}

1.2.2、@XmlType

類級別注解;常與@XMLRootElement,@XmlAccessorType一起使用。

參數 name  定義XML Schema中type的名稱
參數 namespace  指定Schema中的命名空間
參數 propOrder  指定映射XML時的節點順序,使用該屬性時,必須列出JavaBean對象中的所有字段,否則會報錯。
參數 factoryClass  指定UnMarshal時生成映射類實例所需的工廠類,默認為這個類本身
參數 factoryMethod  指定工廠類的工廠方法

@XmlType(propOrder = {"marks", "firstname", "lastname", "nickname"})
public class StudentJaxb {
    private String firstname;
    private String lastname;
    private String nickname;
    private String marks;
    ...
}

1.2.3、@XmlAccessorType

類級別注解;定義這個類中的何種類型需要映射到XML。

參數 value  可以接受4個指定值:
XmlAccessType.FIELD:映射這個類中的所有字段到XML
XmlAccessType.PROPERTY:映射這個類中的屬性(get/set方法)到XML
XmlAccessType.PUBLIC_MEMBER:將這個類中的所有public的field或property同時映射到XML(默認)
XmlAccessType.NONE:不映射

默認的容易導致"類的兩個屬性具有相同名稱"的錯誤,一般可指定為XmlAccessType.FIELD

@XmlAccessorType(XmlAccessType.FIELD)
public class StudentJaxb {
    ...
}

1.2.4、@XmlElement

字段,方法,參數級別注解;該注解可以將被注解的(非靜態)字段,或者被注解的get/set方法對應的字段映射為本地元素,也就是子元素。

參數 name  用於指定映射時的節點名稱,指定生成元素的名字,若不指定,默認使用方法名小寫作為元素名。
參數 namespace  指定映射時的節點命名空間
參數 required  字段是否必須,默認為false
參數 nillable  是否處理空數據,默認為false
參數 type  定義該字段或屬性的關聯類型

public class StudentJaxb {
    @XmlElement(namespace = "http://www.w3.org/TR/html4/school/")
    private String firstname;
    ...
}

1.2.5、@XmlAttribute

字段和方法級別的注解。該注解會將字段或get/set方法對應的字段映射成本類對應元素的屬性。

參數 name  用於指定映射時的節點屬性名稱,若不指定,默認使用方法名小寫作為元素名。
參數 namespace  指定映射時的節點屬性命名空間
參數 required  該屬性是否必須,默認為false

public class StudentJaxb {
    @XmlAttribute
    private int rollno;
    @XmlAttribute(namespace = "http://www.w3.org/TR/html4/school/")
    private int age;
   ...
}

1.2.6、@XmlTransient

類,字段,方法級別的注解。定義某一字段或屬性不需要被映射。

2、JAXB使用

2.1、xml樣例文件

<?xml version="1.0" encoding="utf-8" ?>
<school:grade xmlns:school="http://www.w3.org/TR/html4/school/">
    <school:student rollno="1" school:age="11">
        <school:firstname>cxx1</school:firstname>
        <lastname>Bob1</lastname>
        <nickname>stars1</nickname>
        <marks>85</marks>
    </school:student>
    <school:student rollno="2" school:age="12">
        <school:firstname>cxx2</school:firstname>
        <lastname>Bob2</lastname>
        <nickname>stars2</nickname>
        <marks>85</marks>
    </school:student>
    <school:student rollno="3" school:age="13">
        <school:firstname>cxx3</school:firstname>
        <lastname>Bob3</lastname>
        <nickname>stars3</nickname>
        <marks>85</marks>
    </school:student>
</school:grade>

2.2、xml對應的類

2.2.1、班級類

package com.abc.demo.general.xml;

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

/**
 * 班級
 */
@XmlRootElement(name = "grade", namespace = "http://www.w3.org/TR/html4/school/")
@XmlAccessorType(XmlAccessType.FIELD)
public class GradeJaxb {
    @XmlElement(name = "student", namespace = "http://www.w3.org/TR/html4/school/")
    private List<StudentJaxb> students;

    public List<StudentJaxb> getStudents() {
        return students;
    }

    public void setStudents(List<StudentJaxb> students) {
        this.students = students;
    }

    @Override
    public String toString() {
        return "GradeJaxb{" +
                "students=" + students +
                '}';
    }
}

2.2.2、學生類

package com.abc.demo.general.xml;

import javax.xml.bind.annotation.*;

/**
 * 學生
 */
@XmlType(propOrder = {"marks", "firstname", "lastname", "nickname"})
@XmlAccessorType(XmlAccessType.FIELD)
public class StudentJaxb {
    @XmlAttribute
    private int rollno;
    @XmlAttribute(namespace = "http://www.w3.org/TR/html4/school/")
    private int age;
    @XmlElement(namespace = "http://www.w3.org/TR/html4/school/")
    private String firstname;
    private String lastname;
    private String nickname;
    private String marks;

    public StudentJaxb() {}

    public StudentJaxb(int rollno, int age, String firstname, String lastname, String nickname, String marks) {
        this.rollno = rollno;
        this.age = age;
        this.firstname = firstname;
        this.lastname = lastname;
        this.nickname = nickname;
        this.marks = marks;
    }

    public int getRollno() {
        return rollno;
    }

    public void setRollno(int rollno) {
        this.rollno = rollno;
    }

    public int getAge() {
        return age;
    }

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

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getMarks() {
        return marks;
    }

    public void setMarks(String marks) {
        this.marks = marks;
    }

    @Override
    public String toString() {
        return "StudentJaxb{" +
                "rollno=" + rollno +
                ", age=" + age +
                ", firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", nickname='" + nickname + '\'' +
                ", marks='" + marks + '\'' +
                '}';
    }
}

2.2.3、package-info.java

該文件定義命名空間對應的前綴.

/**
 * 設置命名空間對應的前綴
 */
@XmlSchema(xmlns = {@XmlNs(prefix = "school", namespaceURI = "http://www.w3.org/TR/html4/school/")})
package com.abc.demo.general.xml;

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlSchema;

2.3、JAXB使用例子

該例子演示了使用JAXB來處理O/X轉換:Java對象轉成xml以及xml轉成Java對象。

package com.abc.demo.general.xml;

import org.junit.Test;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

/**
 * jaxb使用
 */
public class JaxbCase {
    /**
     * java對象轉成xml
     * @throws Exception
     */
    @Test
    public void javaToXml() throws Exception {
        List<StudentJaxb> students = new ArrayList<>();
        StudentJaxb student1 = new StudentJaxb(1, 11,"cxx1", "Bob1", "stars1", "85");
        StudentJaxb student2 = new StudentJaxb(2, 12, "cxx2", "Bob2", "stars2", "85");
        StudentJaxb student3 = new StudentJaxb(3, 13, "cxx3", "Bob3", "stars3", "85");
        students.add(student1);
        students.add(student2);
        students.add(student3);
        GradeJaxb grade = new GradeJaxb();
        grade.setStudents(students);

        //獲取JAXB的上下文環境
        JAXBContext context = JAXBContext.newInstance(GradeJaxb.class);
        //創建Marshaller實例
        Marshaller marshaller = context.createMarshaller();
        //設置轉換參數 -> 是否格式化輸出
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        //是否隱藏xml聲明
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
        //構建輸出環境 -> 這里輸出到控制台Console
        PrintStream out = System.out;
        //將所需對象序列化 -> 該方法沒有返回值
        marshaller.marshal(grade, out);
    }

    /**
     * xml轉成java對象
     * @throws Exception
     */
    @Test
    public void xmlToJava() throws Exception {
        //獲取JAXB的上下文環境
        JAXBContext context = JAXBContext.newInstance(GradeJaxb.class);
        //創建UnMarshaller實例
        Unmarshaller unmarshaller = context.createUnmarshaller();
        InputStream in = JaxbCase.class.getResourceAsStream("student2.xml");
        //將XML數據序列化
        GradeJaxb grade = (GradeJaxb) unmarshaller.unmarshal(in);
        System.out.println(grade);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM