使用XStream是实现XML与Java对象的转换(6)--持久化
九、持久化
在第八节的示例中,当我们操作一组对象时,我们可以指定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,简单的存储
程序如下:
- package cn.tjpu.zhw.xml.xstream6;
- import java.io.File;
- import java.util.List;
- import com.thoughtworks.xstream.persistence.FilePersistenceStrategy;
- import com.thoughtworks.xstream.persistence.PersistenceStrategy;
- import com.thoughtworks.xstream.persistence.XmlArrayList;
- public class PersistenceMain {
- public static void main(String[] args) {
- //创建持久化策略(定义存储工具和存储位置)
- //注:d:/tmp是一个已存在的目录,否则会报错
- PersistenceStrategy strategy = new FilePersistenceStrategy(
- new File("d:/tmp"));
- //创建操作工具
- List list = new XmlArrayList(strategy);
- System.out.println("刚创建XmlArrayList对象时list.size()="+list.size());
- //添加数据
- list.add(new Person("张三"));
- list.add(new Person("李四"));
- list.add(new Person("毛毛"));
- list.add(new Person("大熊"));
- System.out.println("添加了4个元素之后list.size()="+list.size());
- //删除“李四”
- list.remove(1);
- System.out.println("删除了1个元素之后list.size()="+list.size());
- }
- }
- class Person {
- public Person(String name) {
- this.name = name;
- }
- private String name;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String toString() {
- return "Person对象的name=" + getName();
- }
- }
运行结果:
- 刚创建XmlArrayList对象时list.size()=0
- 添加了4个元素之后list.size()=4
- 删除了1个元素之后list.size()=3
现在我们查看d:/tmp目录,我们会发现有3个文件int@0.xml、int@1.xml和int@2.xml。这3个文件就是我们存储的3个Person对象,他们的内容分别是:
int@0.xml文件:
- <cn.tjpu.zhw.xml.xstream6.Person>
- <name>张三</name>
- </cn.tjpu.zhw.xml.xstream6.Person>
int@1.xml文件
- <cn.tjpu.zhw.xml.xstream6.Person>
- <name>毛毛</name>
- </cn.tjpu.zhw.xml.xstream6.Person>
int@2.xml文件:
- <cn.tjpu.zhw.xml.xstream6.Person>
- <name>大熊</name>
- </cn.tjpu.zhw.xml.xstream6.Person>
其实,在我们每一次调用add方法的时候,都有一次持久化过程,每次都会将文件写入到d:/tmp目录。
2,所有我们熟悉的操作方法
由于XmlArrayList、XmlMap和XmlSet继承我们熟悉各个集合接口,所以我们可以向操作List、Map和Set一样来操作我们的数据,所不同的是原来我们集合中的数据在内存中,现在却在我们预定义的持久化策略中。
编写程序如下:
- package cn.tjpu.zhw.xml.xstream6;
- import java.io.File;
- import java.util.Iterator;
- import java.util.List;
- import com.thoughtworks.xstream.persistence.FilePersistenceStrategy;
- import com.thoughtworks.xstream.persistence.PersistenceStrategy;
- import com.thoughtworks.xstream.persistence.XmlArrayList;
- public class UsageTestMain {
- // XmlArrayList的用法
- public static void main(String[] args) {
- // 创建持久化策略(定义存储工具和存储位置)
- // 注:d:/tmp是一个已存在的目录,否则会报错
- PersistenceStrategy strategy = new FilePersistenceStrategy(new File(
- "d:/tmp"));
- // 创建操作工具
- List list = new XmlArrayList(strategy);
- System.out.println("刚创建XmlArrayList对象时list.size()="+list.size());
- System.out.println();
- //获取迭代器
- Iterator iter = list.iterator();
- System.out.println("******遍历每一个元素******");
- //遍历每一个元素
- while(iter.hasNext()){
- Person p = (Person)iter.next();
- System.out.println("当前元素p="+p);
- }
- }
- }
运行结果:
- 刚创建XmlArrayList对象时list.size()=3
- ******遍历每一个元素******
- 当前元素p=Person对象的name=张三
- 当前元素p=Person对象的name=毛毛
- 当前元素p=Person对象的name=大熊
3,定制自己的转换器(Local Converter)
由于内存中存储了大量数据,我们可以使用文件系统暂存,内存中只记录存放文件的目录即可,这是我们可以自己定义一个转换器:
- package cn.tjpu.zhw.xml.xstream6;
- import java.io.File;
- import java.util.ArrayList;
- import java.util.Collection;
- import com.thoughtworks.xstream.XStream;
- import com.thoughtworks.xstream.converters.Converter;
- import com.thoughtworks.xstream.converters.MarshallingContext;
- import com.thoughtworks.xstream.converters.UnmarshallingContext;
- import com.thoughtworks.xstream.io.HierarchicalStreamReader;
- import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
- import com.thoughtworks.xstream.persistence.FilePersistenceStrategy;
- import com.thoughtworks.xstream.persistence.XmlArrayList;
- //自己定义一个局部转换器
- public final class LocalArrayListConverter implements Converter {
- private XStream xstream;
- public LocalArrayListConverter(XStream xstream) {
- this.xstream = xstream;
- }
- //将Collection对象序列化到文件中
- //注:序列化时内存中并没有存放集合中的内容,只是暂存了这些文件存放的目录
- public void marshal(Object source, HierarchicalStreamWriter writer,
- MarshallingContext context) {
- File dir = new File("d:/tmp");
- //创建持久化工具,并加载目录中的所有文件
- XmlArrayList list = new XmlArrayList(
- new FilePersistenceStrategy(dir,xstream));
- context.convertAnother(dir);
- //生成文件
- list.addAll((Collection) source);
- }
- //从文件中读取信息,反序列换为Collection对象
- //注:反序列化时会删除暂存目录下的所有文件
- public Object unmarshal(
- HierarchicalStreamReader reader,
- UnmarshallingContext context) {
- File directory = (File) context.convertAnother(null, File.class);
- //创建持久化工具,并加载目录中的所有文件
- XmlArrayList persistentList = new XmlArrayList(
- new FilePersistenceStrategy(directory, xstream));
- //将已加载的信息复制一份到list中
- ArrayList list = new ArrayList(persistentList);
- //删除所有文件
- persistentList.clear();
- //返回已加载的信息
- return list;
- }
- public boolean canConvert(Class type) {
- return type == ArrayList.class;
- }
- }
这个转换器是转换ArrayList对象的。
下面是我们的测试程序:
- package cn.tjpu.zhw.xml.xstream6;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- import com.thoughtworks.xstream.XStream;
- public class LocalConverterMain {
- public static void main(String[] args) {
- XStream xstream = new XStream();
- xstream.alias("volume", Volume.class);
- //使用自定义的转换器LocalArrayListConverter来转换Volume类的documents字段
- //这个转换器是受限制的局部(local)转换器,只能转换Volume类的documents字段
- xstream.registerLocalConverter(Volume.class, "documents",
- new LocalArrayListConverter(xstream));
- //要转换的对象
- Volume volume = new Volume();
- //创建集合
- Collection coll = new ArrayList();
- coll.add(1);
- coll.add(2.123d);
- coll.add(new Person("张三"));
- volume.documents.addAll(coll);
- System.out.println("******序列化******");
- //转换XML
- String xml = xstream.toXML(volume);
- //输出XML
- System.out.println(xml);
- System.out.println("******反序列化******");
- Volume v2 = (Volume)xstream.fromXML(xml);
- for(Object obj:v2.documents){
- System.out.println("obj="+obj);
- }
- }
- }
- abstract class AbstractDocument {
- String title;
- }
- class TextDocument extends AbstractDocument {
- List chapters = new ArrayList();
- }
- class ScannedDocument {
- List images = new ArrayList();
- }
- class Volume {
- List documents = new ArrayList();
- }
运行结果:
- ******序列化******
- <volume>
- <documents>d:\tmp</documents>
- </volume>
- ******反序列化******
- obj=Person对象的name=张三
- obj=Person对象的name=毛毛
- obj=Person对象的name=大熊
- obj=1
- obj=2.123
- obj=Person对象的name=张三
使用XStream是实现XML与Java对象的转换(6)--持久化的更多相关文章
- 使用XStream是实现XML与Java对象的转换(4)--转换器
七.转换器(Converter) 我们程序中的POJO是千变万化的,而且需求也是千奇百怪的,所以XStream中的内置的转换器的功能不一定能够满足我们的要求,所以我们就需要自己构建转换器. 1,一个基 ...
- 使用XStream是实现XML与Java对象的转换(3)--注解
六.使用注解(Annotation) 总是使用XStream对象的别名方法和注册转换器,会让人感到非常的乏味,又会产生很多重复性代码,于是我们可以使用注解的方式来配置要序列化的POJO对象. 1,最基 ...
- 使用XStream是实现XML与Java对象的转换(1)--简介及入门示例
一.简单介绍 XStream是thoughtworks开发的开源框架,用于实现XML数据于Java对象.Json数据的转换.它不需要schema或其他的mapping文件就可以进行java对象和xml ...
- 使用XStream是实现XML与Java对象的转换(5)--Object Stream
八,Object Stream 之前的例子我们都是直接输出Xml成为String类型或者从String中获得并解析Xml,现在我们要处理输入流和输出流! 1,输出流(ObjectOutputStrea ...
- 使用XStream是实现XML与Java对象的转换(2)--别名
五.使用别名(Alias) 首先,有这样一段Java代码: import java.util.ArrayList; import java.util.List; import com.thoughtw ...
- 不规矩的xml与JAVA对象互相转换的小技巧-使用Marshaller
摘要:将XML文档与JAVA对象互转是很常见的需求,如果XML定义很规整这很好实现.然而在现实中“不规矩”的XML可能更常见,Marshaller便无能为力了吗?下面是一个小技巧,调整一下思维便能重用 ...
- XStream轻松转换xml和java对象
首先引入所需的jar: xstream-1.4.9.xpp3_min-1.1.4c.dom4j-1.6.1, 或用maven管理jar包时在pom.xml中添加: <!-- https://mv ...
- xml-mapping xml 与 java 对象转换映射框架,像 XStream 一样优雅地读写xml
xml xml 是 java 实现的 xml 框架. 希望以最优雅的方式进行 xml 和 java 之间的转换处理,一行代码搞定一切. 特点 对象的和 xml 的互相映射 支持注解 @Alias 指定 ...
- XML 和 java对象相互转换
XML 和 java对象相互转换 博客分类: XML 和 JSON 下面使用的是JDK自带的类,没有引用任何第三方jar包. Unmarshaller 类使客户端应用程序能够将 XML 数据转换为 ...
随机推荐
- 14 fragment传值
两个fragment传值 方式一 布局文件代码: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/and ...
- 2.4、Android Studio使用主题编辑器设计主题
Android Studio包含一个叫主题编辑器的可视的助手,可以提供以下功能: 1. 创建和更改你的app主题 2. 为不同的资源适应主题 3. 普通的UI颜色更改的实时显示 主题编辑器 这一节描述 ...
- [ExtJS5学习笔记]第十一节 Extjs5MVVM模式下系统登录实例
本文地址:http://blog.csdn.net/sushengmiyan/article/details/38815923 实例代码下载地址: http://download.csdn.net/d ...
- iOS下JS与OC互相调用(二)--WKWebView 拦截URL
在上篇文章中讲述了使用UIWebView拦截URL的方式来处理JS与OC交互. 由于UIWebView比较耗内存,性能上不太好,而苹果在iOS 8中推出了WKWebView. 同样的用WKWebVie ...
- java基础---Java---面试题---银行业务调度系统(线程同步锁、枚举、线程池)
银行业务调度系统的项目需求: 模拟实现银行业务调度系统逻辑,具体需求如下: Ø 银行内有6个业务窗口,1- 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口. Ø 有三种对应类 ...
- android程序崩溃后重启
有时候由于测试不充分或者程序潜在的问题而导致程序异常崩溃,这个是令人无法接受的,在android中怎样捕获程序的异常崩溃,然后进行一些必要的处理或重新启动 应用这个问题困恼了我很久,今天终于解决了该问 ...
- 【翻译】Ext JS 6.2 早期访问版本发布
原文:Announcing Ext JS 6.2 Early Access 非常开心,Sencha Ext JS 6.2早期访问版本今天发布了.早期访问版本的主要目的是为了让大家进行测试并评估Ext ...
- iOS视图控制器初始化问题
最近在群里见不少人 问到用视图控制器的alloc /init方法初始化的时候,出来的是黑色的空界面.之前我也遇到过,所以在这里总结下. 我们在项目中肯定都会用到自定义的ViewController,而 ...
- Struts2进阶(一)运行原理及搭建步骤
Struts2进阶(一)运行原理 Struts2框架 Struts2框架搭建步骤 致力于web服务,不可避免的涉及到编程实现部分功能.考虑使用到SSH框架中的Struts2.本篇文章只为深入理解Str ...
- Android进阶(一)几种网络请求方式详解
Ref:http://blog.csdn.net/zuolongsnail/article/details/6373051 Android应用经常会和服务器端交互,这就需要手机客户端发送网络请求,下面 ...