XStream浅析

文章目录

  • 一、概述
  • 二、XStream相关jar包
  • 三、创建两个类
  • 四、简单的示例
  • 五、别名
  • 六、指定属性、去除无用Collection类的属性
  • 七、去除不想要的Javabean属性

一、概述

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>dongchengqudescription>
      com.veeja.demo.City>
      <com.veeja.demo.City>
        <name>昌平区name>
        <description>changpingqudescription>
      com.veeja.demo.City>
    cities>
  com.veeja.demo.Province>
  <com.veeja.demo.Province>
    <name>山东省name>
    <cities>
      <com.veeja.demo.City>
        <name>济南name>
        <description>jinandescription>
      com.veeja.demo.City>
      <com.veeja.demo.City>
        <name>青岛name>
        <description>qingdaodescription>
      com.veeja.demo.City>
    cities>
  com.veeja.demo.Province>
list>

我们可以观察一下这个结果:

我们可以明显的看出来,这是一个XML格式的文本。
根元素是, 因为我们是把List对象转换为xml,所以根元素为
第二级为,因为我们Javabean的类型为Province,所以元素的名称就是类的完整名
第三级为,就是Province类内的属性名

五、别名

我们在上面生成的xml中,发现了几个问题:

  1. 根元素是,根据我们的需求,其实这个根元素如果是更合适一点。
  2. 还有中间的,都太长了,而且还有类的包名,这里可以简要一些,换成小写,也就是就可以了。

这个问题怎么解决呢?答案是使用 别名(alias)

我们有这么几个需求:

  • 默认List类型对应元素,希望让List类型对应元素;
  • 默认Province类型对应,希望让它对应
  • 默认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>dongchengqudescription>
      city>
      <city>
        <name>昌平区name>
        <description>changpingqudescription>
      city>
    cities>
  province>
  <province>
    <name>山东省name>
    <cities>
      <city>
        <name>济南name>
        <description>jinandescription>
      city>
      <city>
        <name>青岛name>
        <description>qingdaodescription>
      city>
    cities>
  province>
china>

六、指定属性、去除无用Collection类的属性

我们现在不妨把山东省的那一部分单独拿出来看一看:

<province>
   <name>山东省name>
   <cities>
     <city>
       <name>济南name>
       <description>jinandescription>
     city>
     <city>
       <name>青岛name>
       <description>qingdaodescription>
     city>
   cities>
 province>

首先,我觉得中间的一个cities标签没有什么必要,完全可以去掉,而且name标签,完全可以作为province的一个name属性,而没有必要单独生成一个子元素。

也就是经过处理,如果可以得到这样的形式:

<province name="山东省">
	<city>
		<name>济南name>
		<description>jinandescription>
	city>
	<city>
		<name>青岛name>
		<description>qingdaodescription>
	city>
province>

这样就会简洁的多。

也就是说,默认情况下,Javabean的属性都会生成子元素,但是我们希望生成为元素的属性。

  • 这时我们可以使用xstream.useAttributeFor(Ccc.class, "name");来将Ccc类的name属性,生成的属性。
  • 我们还可以使用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>dongchengqudescription>
    city>
    <city>
      <name>昌平区name>
      <description>changpingqudescription>
    city>
  province>
  <province name="山东省">
    <city>
      <name>济南name>
      <description>jinandescription>
    city>
    <city>
      <name>青岛name>
      <description>qingdaodescription>
    city>
  province>
china>

七、去除不想要的Javabean属性

我们又发现了一个问题,这个属性好像没什么用处。这个属性能不能去掉呢?
这个时候,我们可以使用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.

你可能感兴趣的:(Java,java)