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); } }