XStream 簡介

XStream

一、概述

XStream是Java類庫,用來將對象序列化成XML (JSON)或反序列化爲對象。

也就是說,使用XStream,我們可以把Java對象轉換成XML,也可以將XML轉換爲Java對象。

二、XStream相關jar包

XStream的必導JAR包:

  • 核心JAR包:xstream-1.4.7.jar
  • 必須依賴包:xpp3_min-1.1.4c.jar(XML Pull Parser,一款速度很快的XML解析器)。

三、創建兩個類

爲了演示我們的XStream的用法,我們先創建兩個類,等會作爲演示操作的對象。
其中一個是City類

package com.veeja.demo;

public class City {
	private String name;// 市名
	private String description;// 描述

	public String getName() {
		return name;
	}

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

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String toString() {
		return "City [name=" + name + ", description=" + description + "]";
	}

	public City() {
		super();
		// TODO Auto-generated constructor stub
	}

	public City(String name, String description) {
		super();
		this.name = name;
		this.description = description;
	}
}

另一個是Province類

package com.veeja.demo;

import java.util.ArrayList;
import java.util.List;

public class Province {
	private String name;// 省名
	private List<City> cities = new ArrayList<City>();

	public String getName() {
		return name;
	}

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

	public List<City> getCities() {
		return cities;
	}

	public void setCities(List<City> cities) {
		this.cities = cities;
	}

	public void addCity(City city) {
		cities.add(city);
	}
}

四、簡單的示例

使用XStream,步驟也很簡單。

第一步就是創建XStream對象。

XStream xStream = new XStream();

然後就是使用toXML方法來轉換成xml格式的字符串。

String string = xStream.toXML(proList);

例如以下代碼,
我們運行一下下面的function1()方法,看一下輸出的結果:

@Test
public void function1() {
	List<Province> proList = getProvinceList();
	/*
	 * 創建XStream對象,調用toXML把集合轉換成xml字符串
	 */
	XStream xStream = new XStream();
	String string = xStream.toXML(proList);
	System.out.println(string);
}

public List<Province> getProvinceList() {
	Province p1 = new Province();
	p1.setName("北京");
	p1.addCity(new City("東城區", "dongchengqu"));
	p1.addCity(new City("昌平區", "changpingqu"));

	Province p2 = new Province();
	p1.setName("山東省");
	p1.addCity(new City("濟南", "jinan"));
	p1.addCity(new City("青島", "qingdao"));

	ArrayList<Province> provinceList = new ArrayList<Province>();
	provinceList.add(p1);
	provinceList.add(p2);

	return provinceList;
}

結果:

<list>
  <com.veeja.demo.Province>
    <name>北京</name>
    <cities>
      <com.veeja.demo.City>
        <name>東城區</name>
        <description>dongchengqu</description>
      </com.veeja.demo.City>
      <com.veeja.demo.City>
        <name>昌平區</name>
        <description>changpingqu</description>
      </com.veeja.demo.City>
    </cities>
  </com.veeja.demo.Province>
  <com.veeja.demo.Province>
    <name>山東省</name>
    <cities>
      <com.veeja.demo.City>
        <name>濟南</name>
        <description>jinan</description>
      </com.veeja.demo.City>
      <com.veeja.demo.City>
        <name>青島</name>
        <description>qingdao</description>
      </com.veeja.demo.City>
    </cities>
  </com.veeja.demo.Province>
</list>

我們可以觀察一下這個結果:

  • 我們可以明顯的看出來,這是一個XML格式的文本。
  • 根元素是<list> 因爲我們是把List對象轉換爲xml,所以根元素爲<list>
  • 第二級爲<com.veeja.demo.Province>,因爲我們Javabean的類型爲Province,所以元素的名稱就是類的完整名
  • 第三級爲<name><cities>,就是Province類內的屬性名。
  • 。。。
  • 。。。

五、別名

我們在上面生成的xml中,發現了幾個問題:

  1. 根元素是<list>,根據我們的需求,其實這個根元素如果是<china>更合適一點。
  2. 還有中間的<com.veeja.demo.Province>,都太長了,而且還有類的包名,這裏可以簡要一些,換成小寫,也就是<province>就可以了。

這個問題怎麼解決呢?答案是使用“別名(alias)”。

我們有這麼幾個需求:
默認List類型對應<list>元素,希望讓List類型對應<china>元素;
默認Province類型對應<cn.itcast.demo1.Province>,希望讓它對應<province>
默認City類型對應<cn.itcast.demo1.city>,希望它對應<city>元素。

我們可以使用xstream.alias("aaa",Bbb.class);用來將Bbb類指定別名爲aaa

例如,我們改寫上面的代碼爲:

@Test
public void function2() {
	List<Province> proList = getProvinceList();
	/*
	 * 創建XStream對象,調用toXML把集合轉換成xml字符串
	 */
	XStream xStream = new XStream();
	xStream.alias("china", List.class);
	xStream.alias("province", Province.class);
	xStream.alias("city", City.class);

	String string = xStream.toXML(proList);
	System.out.println(string);
}

我們再看一下結果,已經變成我們想要的樣子了:

<china>
  <province>
    <name>北京</name>
    <cities>
      <city>
        <name>東城區</name>
        <description>dongchengqu</description>
      </city>
      <city>
        <name>昌平區</name>
        <description>changpingqu</description>
      </city>
    </cities>
  </province>
  <province>
    <name>山東省</name>
    <cities>
      <city>
        <name>濟南</name>
        <description>jinan</description>
      </city>
      <city>
        <name>青島</name>
        <description>qingdao</description>
      </city>
    </cities>
  </province>
</china>

六、指定屬性、去除無用Collection類的屬性

我們現在不妨把山東省的那一部分單獨拿出來看一看:

<province>
   <name>山東省</name>
   <cities>
     <city>
       <name>濟南</name>
       <description>jinan</description>
     </city>
     <city>
       <name>青島</name>
       <description>qingdao</description>
     </city>
   </cities>
 </province>

首先,我覺得中間的一個cities標籤沒有什麼必要,完全可以去掉,而且name標籤,完全可以作爲province的一個name屬性,而沒有必要單獨生成一個子元素。
也就是經過處理,如果可以得到這樣的形式:

<province name="山東省">
	<city>
		<name>濟南</name>
		<description>jinan</description>
	</city>
	<city>
		<name>青島</name>
		<description>qingdao</description>
	</city>
</province>

這樣就會簡潔的多。

也就是說,默認情況下,Javabean的屬性都會生成子元素,但是我們希望生成爲元素的屬性。
這時我們可以使用xstream.useAttributeFor(Ccc.class, "name");來將Ccc類的name屬性,生成<ccc>的屬性。
我們還可以使用xStream.addImplicitCollection(Province.class, "cities");來去除Province類的cities(Collection類型的)屬性。

也就是我們再次改寫上面的代碼:

@Test
public void function2() {
	List<Province> proList = getProvinceList();
	/*
	 * 創建XStream對象,調用toXML把集合轉換成xml字符串
	 */
	XStream xStream = new XStream();
	xStream.alias("china", List.class);
	xStream.alias("province", Province.class);
	xStream.alias("city", City.class);
	
	xStream.useAttributeFor(Province.class, "name");
	xStream.addImplicitCollection(Province.class, "cities");
	
	String string = xStream.toXML(proList);
	System.out.println(string);
}

我們看一下輸出的結果:

<china>
  <province name="北京">
    <city>
      <name>東城區</name>
      <description>dongchengqu</description>
    </city>
    <city>
      <name>昌平區</name>
      <description>changpingqu</description>
    </city>
  </province>
  <province name="山東省">
    <city>
      <name>濟南</name>
      <description>jinan</description>
    </city>
    <city>
      <name>青島</name>
      <description>qingdao</description>
    </city>
  </province>
</china>

七、去除不想要的Javabean屬性

我們又發現了一個問題,這個<description>屬性好像沒什麼用處。這個屬性能不能去掉呢?
這個時候,我們可以使用xStream.omitField(City.class, "description");來去除。

改寫代碼:

@Test
public void function2() {
	List<Province> proList = getProvinceList();
	/*
	 * 創建XStream對象,調用toXML把集合轉換成xml字符串
	 */
	XStream xStream = new XStream();
	xStream.alias("china", List.class);
	xStream.alias("province", Province.class);
	xStream.alias("city", City.class);

	xStream.useAttributeFor(Province.class, "name");
	xStream.addImplicitCollection(Province.class, "cities");

	// 讓city類,名爲description的屬性不生成對應的xml屬性
	xStream.omitField(City.class, "description");

	String string = xStream.toXML(proList);
	System.out.println(string);
}

輸出結果:

<china>
  <province name="北京">
    <city>
      <name>東城區</name>
    </city>
    <city>
      <name>昌平區</name>
    </city>
  </province>
  <province name="山東省">
    <city>
      <name>濟南</name>
    </city>
    <city>
      <name>青島</name>
    </city>
  </province>
</china>

END.

發佈了166 篇原創文章 · 獲贊 55 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章