九、持久化

在第八节的示例中,当我们操作一组对象时,我们可以指定Writer、OutputStream来写出序列化后的XML数据,我们还可以指定Reader、InputStream来读取序列化后的XML数据。当我们需要写出和读取文件时都需要指定输入输出流,并且需要明确的调用输入输出方法来实现Java对象的序列化和反序列化,其实我们完全可以让Java对象的序列化和反序列化操作隐性的、自动的完成,这就是我们要学的内容:PersistenceStrategy、XmlArrayList、XmlMap和XmlSet。

PersistenceStrategy是我们的持久化策略,定义了我们的存储和读取协议,是实际做存储和读取XML的工具。XStream框架提供的持久化策略只有FilePersistenceStrategy这一种,即将XML数据持久化到文件系统中,但是我们可以定义自己的持久化策略(比如持久化到数据库中),只要继承PersistenceStrategy接口就行了。

XmlArrayList、XmlMap和XmlSet是我们熟悉的3个集合工具类,它们可以让我们以我们非常熟悉的方式操作Java对象,并且隐性的存储和读取为我们需要的XML。

下面我们以XmlArrayList为例来学习。

1,简单的存储

程序如下:

  1. package cn.tjpu.zhw.xml.xstream6;
  2. import java.io.File;
  3. import java.util.List;
  4. import com.thoughtworks.xstream.persistence.FilePersistenceStrategy;
  5. import com.thoughtworks.xstream.persistence.PersistenceStrategy;
  6. import com.thoughtworks.xstream.persistence.XmlArrayList;
  7. public class PersistenceMain {
  8. public static void main(String[] args) {
  9. //创建持久化策略(定义存储工具和存储位置)
  10. //注:d:/tmp是一个已存在的目录,否则会报错
  11. PersistenceStrategy strategy = new FilePersistenceStrategy(
  12. new File("d:/tmp"));
  13. //创建操作工具
  14. List list = new XmlArrayList(strategy);
  15. System.out.println("刚创建XmlArrayList对象时list.size()="+list.size());
  16. //添加数据
  17. list.add(new Person("张三"));
  18. list.add(new Person("李四"));
  19. list.add(new Person("毛毛"));
  20. list.add(new Person("大熊"));
  21. System.out.println("添加了4个元素之后list.size()="+list.size());
  22. //删除“李四”
  23. list.remove(1);
  24. System.out.println("删除了1个元素之后list.size()="+list.size());
  25. }
  26. }
  27. class Person {
  28. public Person(String name) {
  29. this.name = name;
  30. }
  31. private String name;
  32. public String getName() {
  33. return name;
  34. }
  35. public void setName(String name) {
  36. this.name = name;
  37. }
  38. public String toString() {
  39. return "Person对象的name=" + getName();
  40. }
  41. }

运行结果:

  1. 刚创建XmlArrayList对象时list.size()=0
  2. 添加了4个元素之后list.size()=4
  3. 删除了1个元素之后list.size()=3

现在我们查看d:/tmp目录,我们会发现有3个文件int@0.xml、int@1.xml和int@2.xml。这3个文件就是我们存储的3个Person对象,他们的内容分别是:

int@0.xml文件:

  1. <cn.tjpu.zhw.xml.xstream6.Person>
  2. <name>张三</name>
  3. </cn.tjpu.zhw.xml.xstream6.Person>

int@1.xml文件

  1. <cn.tjpu.zhw.xml.xstream6.Person>
  2. <name>毛毛</name>
  3. </cn.tjpu.zhw.xml.xstream6.Person>

int@2.xml文件:

  1. <cn.tjpu.zhw.xml.xstream6.Person>
  2. <name>大熊</name>
  3. </cn.tjpu.zhw.xml.xstream6.Person>

其实,在我们每一次调用add方法的时候,都有一次持久化过程,每次都会将文件写入到d:/tmp目录。

2,所有我们熟悉的操作方法

由于XmlArrayList、XmlMap和XmlSet继承我们熟悉各个集合接口,所以我们可以向操作List、Map和Set一样来操作我们的数据,所不同的是原来我们集合中的数据在内存中,现在却在我们预定义的持久化策略中。

编写程序如下:

  1. package cn.tjpu.zhw.xml.xstream6;
  2. import java.io.File;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import com.thoughtworks.xstream.persistence.FilePersistenceStrategy;
  6. import com.thoughtworks.xstream.persistence.PersistenceStrategy;
  7. import com.thoughtworks.xstream.persistence.XmlArrayList;
  8. public class UsageTestMain {
  9. // XmlArrayList的用法
  10. public static void main(String[] args) {
  11. // 创建持久化策略(定义存储工具和存储位置)
  12. // 注:d:/tmp是一个已存在的目录,否则会报错
  13. PersistenceStrategy strategy = new FilePersistenceStrategy(new File(
  14. "d:/tmp"));
  15. // 创建操作工具
  16. List list = new XmlArrayList(strategy);
  17. System.out.println("刚创建XmlArrayList对象时list.size()="+list.size());
  18. System.out.println();
  19. //获取迭代器
  20. Iterator iter = list.iterator();
  21. System.out.println("******遍历每一个元素******");
  22. //遍历每一个元素
  23. while(iter.hasNext()){
  24. Person p = (Person)iter.next();
  25. System.out.println("当前元素p="+p);
  26. }
  27. }
  28. }

运行结果:

  1. 刚创建XmlArrayList对象时list.size()=3
  2. ******遍历每一个元素******
  3. 当前元素p=Person对象的name=张三
  4. 当前元素p=Person对象的name=毛毛
  5. 当前元素p=Person对象的name=大熊

3,定制自己的转换器(Local Converter)

由于内存中存储了大量数据,我们可以使用文件系统暂存,内存中只记录存放文件的目录即可,这是我们可以自己定义一个转换器:

  1. package cn.tjpu.zhw.xml.xstream6;
  2. import java.io.File;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import com.thoughtworks.xstream.XStream;
  6. import com.thoughtworks.xstream.converters.Converter;
  7. import com.thoughtworks.xstream.converters.MarshallingContext;
  8. import com.thoughtworks.xstream.converters.UnmarshallingContext;
  9. import com.thoughtworks.xstream.io.HierarchicalStreamReader;
  10. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
  11. import com.thoughtworks.xstream.persistence.FilePersistenceStrategy;
  12. import com.thoughtworks.xstream.persistence.XmlArrayList;
  13. //自己定义一个局部转换器
  14. public final class LocalArrayListConverter implements Converter {
  15. private XStream xstream;
  16. public LocalArrayListConverter(XStream xstream) {
  17. this.xstream = xstream;
  18. }
  19. //将Collection对象序列化到文件中
  20. //注:序列化时内存中并没有存放集合中的内容,只是暂存了这些文件存放的目录
  21. public void marshal(Object source, HierarchicalStreamWriter writer,
  22. MarshallingContext context) {
  23. File dir = new File("d:/tmp");
  24. //创建持久化工具,并加载目录中的所有文件
  25. XmlArrayList list = new XmlArrayList(
  26. new FilePersistenceStrategy(dir,xstream));
  27. context.convertAnother(dir);
  28. //生成文件
  29. list.addAll((Collection) source);
  30. }
  31. //从文件中读取信息,反序列换为Collection对象
  32. //注:反序列化时会删除暂存目录下的所有文件
  33. public Object unmarshal(
  34. HierarchicalStreamReader reader,
  35. UnmarshallingContext context) {
  36. File directory = (File) context.convertAnother(null, File.class);
  37. //创建持久化工具,并加载目录中的所有文件
  38. XmlArrayList persistentList = new XmlArrayList(
  39. new FilePersistenceStrategy(directory, xstream));
  40. //将已加载的信息复制一份到list中
  41. ArrayList list = new ArrayList(persistentList);
  42. //删除所有文件
  43. persistentList.clear();
  44. //返回已加载的信息
  45. return list;
  46. }
  47. public boolean canConvert(Class type) {
  48. return type == ArrayList.class;
  49. }
  50. }

这个转换器是转换ArrayList对象的。

下面是我们的测试程序:

  1. package cn.tjpu.zhw.xml.xstream6;
  2. import java.util.ArrayList;
  3. import java.util.Collection;
  4. import java.util.List;
  5. import com.thoughtworks.xstream.XStream;
  6. public class LocalConverterMain {
  7. public static void main(String[] args) {
  8. XStream xstream = new XStream();
  9. xstream.alias("volume", Volume.class);
  10. //使用自定义的转换器LocalArrayListConverter来转换Volume类的documents字段
  11. //这个转换器是受限制的局部(local)转换器,只能转换Volume类的documents字段
  12. xstream.registerLocalConverter(Volume.class, "documents",
  13. new LocalArrayListConverter(xstream));
  14. //要转换的对象
  15. Volume volume = new Volume();
  16. //创建集合
  17. Collection coll = new ArrayList();
  18. coll.add(1);
  19. coll.add(2.123d);
  20. coll.add(new Person("张三"));
  21. volume.documents.addAll(coll);
  22. System.out.println("******序列化******");
  23. //转换XML
  24. String xml = xstream.toXML(volume);
  25. //输出XML
  26. System.out.println(xml);
  27. System.out.println("******反序列化******");
  28. Volume v2 = (Volume)xstream.fromXML(xml);
  29. for(Object obj:v2.documents){
  30. System.out.println("obj="+obj);
  31. }
  32. }
  33. }
  34. abstract class AbstractDocument {
  35. String title;
  36. }
  37. class TextDocument extends AbstractDocument {
  38. List chapters = new ArrayList();
  39. }
  40. class ScannedDocument {
  41. List images = new ArrayList();
  42. }
  43. class Volume {
  44. List documents = new ArrayList();
  45. }

运行结果:

  1. ******序列化******
  2. <volume>
  3. <documents>d:\tmp</documents>
  4. </volume>
  5. ******反序列化******
  6. obj=Person对象的name=张三
  7. obj=Person对象的name=毛毛
  8. obj=Person对象的name=大熊
  9. obj=1
  10. obj=2.123
  11. obj=Person对象的name=张三

使用XStream是实现XML与Java对象的转换(6)--持久化的更多相关文章

  1. 使用XStream是实现XML与Java对象的转换(4)--转换器

    七.转换器(Converter) 我们程序中的POJO是千变万化的,而且需求也是千奇百怪的,所以XStream中的内置的转换器的功能不一定能够满足我们的要求,所以我们就需要自己构建转换器. 1,一个基 ...

  2. 使用XStream是实现XML与Java对象的转换(3)--注解

    六.使用注解(Annotation) 总是使用XStream对象的别名方法和注册转换器,会让人感到非常的乏味,又会产生很多重复性代码,于是我们可以使用注解的方式来配置要序列化的POJO对象. 1,最基 ...

  3. 使用XStream是实现XML与Java对象的转换(1)--简介及入门示例

    一.简单介绍 XStream是thoughtworks开发的开源框架,用于实现XML数据于Java对象.Json数据的转换.它不需要schema或其他的mapping文件就可以进行java对象和xml ...

  4. 使用XStream是实现XML与Java对象的转换(5)--Object Stream

    八,Object Stream 之前的例子我们都是直接输出Xml成为String类型或者从String中获得并解析Xml,现在我们要处理输入流和输出流! 1,输出流(ObjectOutputStrea ...

  5. 使用XStream是实现XML与Java对象的转换(2)--别名

    五.使用别名(Alias) 首先,有这样一段Java代码: import java.util.ArrayList; import java.util.List; import com.thoughtw ...

  6. 不规矩的xml与JAVA对象互相转换的小技巧-使用Marshaller

    摘要:将XML文档与JAVA对象互转是很常见的需求,如果XML定义很规整这很好实现.然而在现实中“不规矩”的XML可能更常见,Marshaller便无能为力了吗?下面是一个小技巧,调整一下思维便能重用 ...

  7. XStream轻松转换xml和java对象

    首先引入所需的jar: xstream-1.4.9.xpp3_min-1.1.4c.dom4j-1.6.1, 或用maven管理jar包时在pom.xml中添加: <!-- https://mv ...

  8. xml-mapping xml 与 java 对象转换映射框架,像 XStream 一样优雅地读写xml

    xml xml 是 java 实现的 xml 框架. 希望以最优雅的方式进行 xml 和 java 之间的转换处理,一行代码搞定一切. 特点 对象的和 xml 的互相映射 支持注解 @Alias 指定 ...

  9. XML 和 java对象相互转换

    XML 和 java对象相互转换 博客分类: XML 和 JSON   下面使用的是JDK自带的类,没有引用任何第三方jar包. Unmarshaller 类使客户端应用程序能够将 XML 数据转换为 ...

随机推荐

  1. Servlet中的跳转(redirect和forward)

    Forward是通过RequestDispatcher对象的forward(HttpServletRequest request,HttpServletResponse response)方法来实现的 ...

  2. Android开发学习之路--RxAndroid之简单原理

      学习了RxAndroid,其实也就是RxJava了,但是还是不是非常清楚到底RxAndroid有什么用呢?为什么要使用RxAndroid呢?这篇文章讲得不错,RxJava的原理.但是这里还是把整个 ...

  3. 09 ListView监听 ExpandableListView的使用总结

    1.ListView的滚动监听 >setOnScrollListener 监听 //ListVIew滚动监听 lv.setOnScrollListener(new OnScrollListene ...

  4. Java spi机制浅谈

    最近看到公司的一些框架和之前看到的开源的一些框架的一些服务发现和接入都采用了java的spi机制. 所以简单的总结下java spi机制的思想. 我们系统里抽象的各个模块,往往有很多不同的实现方案,比 ...

  5. CMake设置FOLDER失败及解决

    CMake可以设置FOLDER属性,用来分目录组织VC中的多个工程. FOLDER: Set the folder name. Use to organize targets in an IDE. T ...

  6. 可视化分析工具Cytoscape使用记录

    最近项目要使用到可视化分析工具Cytoscape,所以会花费很多的时间跟精力来整理Cytoscape软件使用和开发的相关资料,希望写下的文章能减少有兴趣的同行学习跟开发所走的弯路时间.同时也是因为百度 ...

  7. Beanstalkd 一个高性能分布式内存队列系统

    需要一个分布式内存队列,能支持这些特性:任务不重不漏的分发给消费者(最基础的).分布式多点部署.任务持久化.批量处理.错误重试..... 转载:http://rdc.taobao.com/blog/c ...

  8. Linux下jetty报java.lang.OutOfMemoryError: PermGen space及Jetty内存配置调优解决方案

    Linux下的jetty报java.lang.OutOfMemoryError: PermGen space及Jetty内存配置调优解决方案问题linux的jetty下发布程序后再启动jetty服务时 ...

  9. Ubuntu文件中文乱码

    如图,该文件在gedit打开中文显示正常 在命令行中用vim打开,显示内容如下: 使用命令进行编码转换 iconv -f gbk -t utf8 ./SogouQ.mini > ./sougou ...

  10. 【Unity Tips】备忘录(扫盲篇)

    写在前面 Unity3D虽然是个非常方便的游戏引擎,但还是有一些地方会产生一些让人莫名其妙的问题,而且debug半天也不知道到底哪里错了.往往在经过了大量的log之后,也许我们才顿悟,原来Unity内 ...