JAXB 深入顯出 - JAXB 教程 XML轉Java物件初探(Unmarshaller)
摘要: JAXB 作為JDK的一部分,能便捷地將Java物件與XML進行相互轉換,本教程從實際案例出發來講解JAXB 2 的那些事兒。完整版目錄
前情回顧
之前介紹的都是將Java物件轉換為XML,這一節開始,將講述XML資料轉換為JAVA物件。
資料準備
現在有一段XML資料如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Employee>
<id>111</id>
<name>Test</name>
</ Employee>
我將其保存於檔案lesson16.xml
中。
下面是一個經典的Java bean宣告方式,加入了JAXB標籤,並且實現了toString()
方法便於除錯。
@XmlRootElement(name= "Employee")
public class Employee {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName () {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
}
XML檔案
下面演示了將XML檔案資料反編組(反序列化):
@Test
public void test1() throws JAXBException {
JAXBContext context = JAXBContext. newInstance(Employee.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Employee employee = (Employee)unmarshaller.unmarshal(new File("./src/test/resources/lesson16.xml"));
System.out.println(employee);//Employee [id=111, name=Test]
}
得到的結果:
Employee [id=111, name=Test]
XML stream
下面演示了將XML stream資料反編組(反序列化):
@Test
public void test11() throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Employee.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Employee employee = (Employee)unmarshaller.unmarshal(GenerateBean.class.getResourceAsStream("/lesson16.xml"));
System.out.println(employee);//Employee [id=111, name=Test]
}
得到的結果:
Employee [id=111, name=Test]
XML InputStream
下面演示了將XML InputStream 資料反編組(反序列化):
@Test
public void test2() throws JAXBException, IOException {
JAXBContext context = JAXBContext.newInstance(Employee.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
InputStream is = new FileInputStream("./src/test/resources/lesson16.xml");
Employee employee = (Employee)unmarshaller.unmarshal(is);
System.out.println(employee);//Employee [id=111, name=Test]
}
得到的結果:
Employee [id=111, name=Test]
XML URL
在演示URL前,先說明一下資料。我在w3school 上找到一個XML文件,其地址http://www.w3school.com.cn/example/xmle/note.xml
,內容如下:
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
為此,我準備了Java bean如下:
@XmlRootElement
public class Note {
private String to;
private String from;
private String heading;
private String body;
// ignore setters/getters,toString
}
下面演示了將XML URL 資料反編組(反序列化):
@Test
public void test3() throws JAXBException, IOException {
JAXBContext context = JAXBContext.newInstance(Note.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
URL url = new URL("http://www.w3school.com.cn/example/xmle/note.xml");
Note note = (Note)unmarshaller.unmarshal(url);
System.out.println(note);//Note [to=George, from=John, heading=Reminder, body=Don't forget the meeting!]
}
得到的結果:
Note [to=George, from=John, heading=Reminder, body=Don't forget the meeting!]
XML StreamSource
下面演示了將XML StreamSource 資料反編組(反序列化):
@Test
public void test4() throws JAXBException, IOException {
JAXBContext context = JAXBContext.newInstance(Employee.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
String xmlStr = "<Employee><id>1504</id><name>Test</name></Employee>";
Employee employee = (Employee)unmarshaller.unmarshal(new StreamSource(new StringReader(xmlStr)));
System.out.println(employee);//Employee [id=1504, name=Test]
}
得到的結果:
Employee [id=1504, name=Test]
XML Node
下面演示了將XML Document 資料反編組(反序列化):
@Test
public void test5() throws Exception {
JAXBContext context = JAXBContext.newInstance(Employee.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
//建立 Document
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(new File("./src/test/resources/lesson16.xml"));
Employee employee = (Employee)unmarshaller.unmarshal(document);
System.out.println(employee);//Employee [id=111, name=Test]
}
得到的結果:
Employee [id=111, name=Test]
方法延伸
一般來說,unmarshaller.unmarshal()
返回一個Object,需要強制型別轉換,才能得到想要的結果。而有幾個資料來源不止能返回Object,還可以返回JAXBElement
,像下面這樣:
@Test
public void test6() throws Exception {
JAXBContext context = JAXBContext.newInstance(Employee.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
//建立 Document
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(new File("./src/test/resources/lesson16.xml"));
JAXBElement<Employee> ele = unmarshaller.unmarshal(document, Employee.class);
System.out.println(ele.getValue());//Employee [id=111, name=Test]
}
過載方法unmarshaller.unmarshal()
接收兩個引數,第二個引數就是我們需要的型別,然後使用其 getValue()
獲取資料,避免強制型別轉換。
靜態方法
在之前已經接觸過JAXB的靜態方法,它可以簡化程式碼,並且易用性也大大提高。
@Test
public void test7() throws JAXBException {
Employee employee = JAXB.unmarshal(new File("./src/test/resources/lesson16.xml"), Employee.class);
System.out.println(employee);//Employee [id=111, name=Test]
}
得到相同的結果:
Employee [id=111, name=Test]
還有很多種方式沒有列舉,它們的應用場景不多,反序列化和序列化也大同小異,因此沒有全部演示。
Unmarshalling 可以反序列化整個XML或者XML文件的一部分。
Unmarshalling 不會返回 null,如果無法將XML對映到Java物件,程式將直接報錯。
完整程式碼
可以在GitHub找到完整程式碼。
本節程式碼均在該包下:package com.example.demo.lesson16;
下節預覽
本節介紹了 JAXB 將 XML 轉化為Java物件的高階操作。