“小伙子,還不快!我還有兩節課要教給你!”
“兩個?哇。好吧,好吧。你不會做什麼來增強自己的冷靜!我洗耳恭聽。”
“XML 和 JSON 一樣,經常在不同程序和計算機之間傳遞數據時使用。並且有幾種框架可以大大簡化 Java 程序員在使用 XML 時的生活。今天我將向您介紹其中的一種。”
“JAXB 是用於處理 XML 的優秀多用途框架。”
“JAXB 是 JDK 的一部分,因此您無需單獨下載。”
“我先給大家舉個例子,具體怎麼用,然後我們再分析,比如:”
public static void main(String[] args) throws JAXBException
{
// Create an object to be serialized into XML
Cat cat = new Cat();
cat.name = "Missy";
cat.age = 5;
cat.weight = 4;
// Write the result of the serialization to a StringWriter
StringWriter writer = new StringWriter();
// Create a Marshaller object that will perform the serialization
JAXBContext context = JAXBContext.newInstance(Cat.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// And here's the serialization itself:
marshaller.marshal(cat, writer);
// Convert everything written to the StringWriter
String result = writer.toString();
System.out.println(result);
}
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
public String name;
public int age;
public int weight;
public Cat()
{
}
}
<cat> <name> Missy </name> <age> 5 </age> <weight> 4 </weight> </cat>
“出於某種原因,一行一行地,這段代碼讓我想起了 JSON 序列化。相同的註釋,但 JSON 使用了 ObjectMapper,而這使用了 Context 和 Marshaller。”
“是的。他們真的很相似。傑克遜是以 JAXB 為藍本的。但 JAXB 也是從某個地方復制的。你不能從頭開始發明天才。”
“好像是這樣。”
“好的,這就是發生的事情:”
“在第 4-7 行中,我們創建了一個Cat對象並用數據填充它。”
“在第 10 行,我們創建了一個 Writer 對象來寫入結果。”
“在第 13 行,我們創建了‘context’。這類似於 ObjectMapper,但隨後從中創建了兩個額外的子對象。Marshaller用於序列化,而Unmarshaller用於反序列化。與 Jackson 有細微差別,但它不是根本不同。”
“在第 14 行,我們創建了一個Marshaller對象。Marshalling 是序列化的同義詞。”
“在第 15 行,我們將 FORMATTED_OUTPUT 屬性設置為 TRUE。這將在結果中添加換行符和空格,以便代碼易於閱讀,而不是將所有文本都放在一行中。”
“在第 17 行,我們序列化對象。”
“在第 20-21 行,我們在屏幕上顯示序列化的結果。”
“什麼是 @XmlType(name = 'cat&') 和 @XmlRootElement 註釋?”
" @XmlRootElement表示這個對象可以是 XML 元素的'樹根'。換句話說,它可以是最高級別的元素,並且可以包含所有其他元素。"
" @XmlType(name = 'cat')表示該類參與了 JAXB 序列化,同時也為該類指定了 XML 標籤的名稱。"
“好吧,現在我將向您展示一個 XML 反序列化的示例:”
public static void main(String[] args) throws JAXBException
{
String xmldata = "<cat><name>Missy</name><age>5</age><weight>4</weight></cat>";
StringReader reader = new StringReader(xmldata);
JAXBContext context = JAXBContext.newInstance(Cat.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Cat cat = (Cat) unmarshaller.unmarshal(reader);
}
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
public String name;
public int age;
public int weight;
public Cat()
{
}
}
“一切都和傑克遜幾乎一樣。但為了以防萬一,我會解釋這裡發生的一切。”
“在第 3 行,我們傳遞了一個存儲要反序列化的 XML 的字符串。”
“在第 4 行,我們將 XML 字符串包裝在StringReader中。”
“在第 6 行中,我們創建了一個JAXB 上下文,我們將類列表傳遞給它。”
“在第 7 行,我們創建了一個Unmarshaller——將執行反序列化的對象。”
“在第 9 行中,我們從 reader 對象反序列化 XML 並獲得一個 Cat 對象。”
“現在一切似乎都很明顯。但幾個小時前,我還在絞盡腦汁想弄清楚它是如何工作的。”
“當你變得更聰明時,這總會發生。複雜的事情變得簡單。”
“我變聰明了?我不禁為此感到高興。”
“太好了。下面是一個註釋列表,您可以使用它來控制 JAXB 序列化的結果:”
JAXB 註釋 | 描述 |
---|---|
@XmlElement(名稱) | 放置在田野附近。 該字段將存儲在 XML 元素中。 讓您設置標籤的名稱。 |
@XmlAttribute(名稱) | 放置在田野附近。 該字段將存儲為 XML 屬性! 讓您設置屬性的名稱。 |
@XmlElementWrapper(nillable = true) | 放置在田野附近。 允許您為一組元素設置“包裝標籤”。 |
@Xml類型 | 放在班級附近。 如果默認構造函數是私有的,則允許您指定用於創建對象的方法。 |
@XmlJavaTypeAdapter | 放置在田野附近。 允許您指定將字段轉換為字符串的類。 |
“多麼有趣!但是你能給我提供一個使用這些註釋的例子嗎?解釋是一回事,但一個有效的例子是另一回事。”
“好的。我會給你看一個例子。我只是想補充一點,JAXB 允許你註釋 getter/setter 方法而不是字段。”
“這是我承諾的例子:”
public static void main(String[] args) throws JAXBException
{
// Create Cat and Zoo objects to be serialized into XML
Cat cat = new Cat();
cat.name = "Missy";
cat.age = 5;
cat.weight = 4;
Zoo zoo = new Zoo();
zoo.animals.add(cat);
zoo.animals.add(cat);
// Write the result of the serialization to a StringWriter
StringWriter writer = new StringWriter();
// Create a Marshaller object that will perform the serialization
JAXBContext context = JAXBContext.newInstance(Cat.class, Zoo.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// Here's the serialization itself
marshaller.marshal(zoo, writer);
// Convert everything written to the StringWriter into a String
System.out.println(writer.toString());
}
@XmlType(name = "zoo")
@XmlRootElement
public class Zoo
{
@XmlElementWrapper(name = "wild-animals", nillable = true)
@XmlElement(name = "tiger")
public List<Cat> animals = new ArrayList<>();
}
public class Cat
{
@XmlElement(name = "catname")
public String name;
@XmlAttribute(name = "age")
public int age;
@XmlAttribute(name = "w")
public int weight;
public Cat()
{
}
}
< 動物園> <野生動物 > <tiger age = "5" w = "4"> <catname>Missy</catname> </tiger> <tiger age = "5" w = "4"> <catname>Missy </貓名> < /老虎> < /野生動物> </動物園>
“請注意,這次我們沒有序列化 Cat 對象,而是一個存儲 Cat 對象集合的 Zoo 對象。”
“cat 對像被添加到集合中兩次,所以它在 XML 中出現了兩次。”
“該系列有自己的‘野生動物’標籤,包裹了該系列的所有元素。”
“ age & weight元素已經變成了age &w w 屬性。”
“使用@XmlElement屬性,我們將cat 標籤更改為 tiger 標籤。”
“注意第 17 行。這裡我們將兩個類(Zoo和Cat)傳遞給 JAXB 上下文,因為它們都參與序列化。”
“今天是非常有趣的一天。有很多新信息。”
“是的,我為你感到高興。現在,稍微休息一下,我們繼續。”
GO TO FULL VERSION